Play music from JSON data using retrofit2 and rxjava2 in Android

Play music from JSON

RxJava is a Reactive Extensions library for the Java Virtual Machine. It is for composing asynchronous and event based programs using observable sequences for the Java Virtual Machine.

In this tutorial, we will be using RxJava2 and Retrofit2 for performing network operations and parse JSON Data using Retrofit2 and Rxjava2 in Android and display in Recyclerview using cardview. The JSON Data contains a link with music in it and we will play that music in the android app.

More about Retrofit, It is a type-safe rest client for java and android. It is developed by “Square”. Android Retrofit API is one of the most useful libraries which makes life of Android App Developers easy to communicate with the server and get the data back from the server.

Scope:Fetch music from JSON using retrofit2 and rxjava2 and play them in Android app.

IDE: Android Studio.

JSON Link: https://api.myjson.com/bins/mxcsl

Procedure:

Step 1:Go to project level build.gradle file and add the following code into dependencies.

dependencies {
	compile'com.squareup.retrofit2:retrofit:2.1.0'
	compile'com.squareup.retrofit2:converter-gson:2.1.0'
	compile'io.reactivex.rxjava2:rxjava:2.0.1'
	compile'io.reactivex.rxjava2:rxandroid:2.0.1'
	compile'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
}					

This adds retrofit2 and rxjava2 libraries in the project.

Step 2: Go to Android Manifest file and add the following code.

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

This allow the app to have access to the Internet.

Step 3: Create a Model Class App.java. Below is the code for Model Class.

importcom.google.gson.annotations.Expose;
importcom.google.gson.annotations.SerializedName;

importjava.io.Serializable;

public class App implements Serializable {

@SerializedName("itemId")
@Expose
privateString itemId;
@SerializedName("desc")
@Expose
privateString desc;
@SerializedName("audio")
@Expose
privateString audio;

publicApp(String itemId, String desc, String audio) {
this.itemId= itemId;
this.desc= desc;
this.audio= audio;
   }
publicString getId() {
returnitemId;
   }

publicString getDesc() {
returndesc;
   }

publicString getAudio() {
returnaudio;
   }
}				

Step 4:Wrap the List of data of App.java Class with another model class.

importcom.google.gson.annotations.SerializedName;
importcom.saketkumar.perpule.data.model.App;

importjava.util.List;

public class DataManager {

@SerializedName("data")
privateListdataList;

publicListgetDataList() {
returndataList;
   }

public void setDataList(List list) {
dataList= list;
   }

}				

Step 5: Create an Interface to fetch the JSON data using retrofit2 and rxjava2. Below is the code for Interface:

importcom.google.gson.annotations.SerializedName; importcom.saketkumar.perpule.data.model.App; importjava.util.List; public class DataManager { @SerializedName("data") privateList<App>dataList; publicList<App>getDataList() { returndataList; } public void setDataList(List<App> list) { dataList= list; } }

Step 5: Create an Interface to fetch the JSON data using retrofit2 and rxjava2. Below is the code for Interface:

importcom.saketkumar.perpule.data.DataManager;

importio.reactivex.Observable;
importretrofit2.http.GET;

public interface RequestInterface {

@GET("bins/mxcsl/")
   Observable<DataManager>register();
}
}

Step 6: Now create a recycler_row.xml layout for displaying them in the app in list view.

<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" card_view:cardBackgroundColor="@color/colorPrimary" card_view:cardCornerRadius="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="20dp" android:orientation="vertical" android:scaleType="fitXY"> <TextView android:id="@+id/tv_desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" android:textColor="#fff" android:textSize="18sp" android:textStyle="bold" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/tv_desc" android:layout_alignParentStart="true" android:src="@drawable/ic_music_24dp" /> <ImageView android:id="@+id/ib_play_circle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:visibility="visible" android:src="@drawable/ic_play_circle_24dp" android:tag="play" /> </RelativeLayout> </android.support.v7.widget.CardView>

This layout will look something like this:

Play music from JSON

Now we need to put them in a recyclerviewList. So now create activity_main.xml layout and write the below code.

<?xml version="1.0" encoding="utf-8"?> <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.saketkumar.perpule.ui.main.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:scrollbars="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>

This will look something like this :

Play music from JSON

Step 7:Now create a DataAdapter.Java class which extends RecyclerView to provide a bridge between data and displaying the view. Below is the code for this class:

importandroid.app.Activity; importandroid.content.Context; importandroid.content.Intent; importandroid.media.AudioManager; importandroid.media.MediaPlayer; importandroid.os.Bundle; importandroid.support.v7.widget.RecyclerView; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.ViewGroup; importandroid.widget.ImageView; importandroid.widget.TextView; importjava.io.IOException; importjava.util.ArrayList; public class DataAdapterextends RecyclerView.Adapter<DataAdapter.ViewHolder> { privateArrayList<App>mAndroidList; privateMediaPlayermPlayer; publicDataAdapter(ArrayList<App>androidList) { mAndroidList= androidList; } @Override publicViewHolderonCreateViewHolder(ViewGroup parent, intviewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_row, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, intposition) { holder.mTvDesc.setText(mAndroidList.get(position).getDesc()); holder.mIbPlay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(holder.mIbPlay.getTag().toString().equals("play")) { try{ mPlayer= new MediaPlayer(); mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mPlayer.setDataSource(mAndroidList.get(position).getAudio()); mPlayer.prepare(); mPlayer.start(); holder.mIbPlay.setTag("pause"); holder.mIbPlay.setImageResource(R.drawable.ic_pause_circle_24dp); } catch (IOException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } } else if (mPlayer.isPlaying()) { mPlayer.pause(); holder.mIbPlay.setTag("play"); holder.mIbPlay.setImageResource(R.drawable.ic_play_circle_24dp); } } }); } @Override publicintgetItemCount() { returnmAndroidList.size(); } public class ViewHolderextends RecyclerView.ViewHolder{ privateTextViewmTvDesc,mTvAudio; privateImageViewmIbPlay,mIbPause; publicViewHolder(View view) { super(view); mTvDesc= (TextView)view.findViewById(R.id.tv_desc); mIbPlay= (ImageView) view.findViewById(R.id.ib_play_circle); } } }

Step 8 : Now in MainActivity.java class , We will load the json and display them in the list view. Below is the code for this class:

importandroid.os.Bundle; importandroid.support.v7.widget.LinearLayoutManager; importandroid.support.v7.widget.LinearSnapHelper; importandroid.support.v7.widget.RecyclerView; importandroid.support.v7.widget.SnapHelper; importandroid.widget.Toast; importcom.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; importjava.util.ArrayList; importjava.util.List; importio.reactivex.android.schedulers.AndroidSchedulers; importio.reactivex.disposables.CompositeDisposable; importio.reactivex.schedulers.Schedulers; importretrofit2.Retrofit; importretrofit2.converter.gson.GsonConverterFactory; public class MainActivityextends BaseActivityimplements MainMvpView { privateRecyclerViewmRecyclerView; privateCompositeDisposablemCompositeDisposable; privateDataAdaptermAdapter; privateArrayList<App>mAndroidArrayList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mCompositeDisposable= new CompositeDisposable(); initRecyclerView(); loadJSON(); } private void initRecyclerView() { mRecyclerView= (RecyclerView) findViewById(R.id.recycler_view); mRecyclerView.setHasFixedSize(true); RecyclerView.LayoutManagerlayoutManager = new LinearLayoutManager(getApplicationContext()); mRecyclerView.setLayoutManager(layoutManager); SnapHelpermSnapHelper = new LinearSnapHelper(); mSnapHelper.attachToRecyclerView(mRecyclerView); } private void loadJSON() { RequestInterfacerequestInterface = new Retrofit.Builder() .baseUrl(“https://api.myjson.com/”) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build().create(RequestInterface.class); mCompositeDisposable.add(requestInterface.register() .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(this::handleResponse,this::handleError)); } public void handleResponse(DataManagerresponseData) { if(responseData != null){ List<App>dataList = responseData.getDataList(); mAndroidArrayList= new ArrayList<>(); if(dataList!= null){ mAndroidArrayList.addAll(dataList); } mAdapter= new DataAdapter(mAndroidArrayList); mRecyclerView.setAdapter(mAdapter); } } private void handleError(Throwable error) { Toast.makeText(this, "Error "+error.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } @Override public void onDestroy() { super.onDestroy(); mCompositeDisposable.clear(); } }

Final Result will be something like this:

Play music from JSON

Conclusion:

Run the application and you can see that all API data is displayed in Recycler view with card view using Retrofit2 and Rxjava2. And you play the music by clicking on the play button.