Full Source Code Download Here:
https://github.com/sanjaymangaroliya/MarvelApiIntegration.git
MainActivity
package com.zt.marvelapiintegration.activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.GridView;
import android.widget.TextView;
import com.zt.marvelapiintegration.R;
import com.zt.marvelapiintegration.global.GlobalConstant;
import com.zt.marvelapiintegration.global.Utils;
import com.zt.marvelapiintegration.restapicall.AsyncTaskCompleteListener;
import com.zt.marvelapiintegration.restapicall.ParseController;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private GridView grid_view;
private ArrayList<HashMap<String, String>> comicList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Toolbar
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTitle("");
initUI();
}
private void initUI() {
TextView tvTitle = findViewById(R.id.tv_title);
tvTitle.setText("Comic News");
grid_view = findViewById(R.id.grid_view);
getComicNews();
}
private void getComicNews() {
Map<String, String> map = new HashMap<>();
map.put("url", GlobalConstant.URL + GlobalConstant.COMICS);
map.put("ts", "1");
map.put("apikey", GlobalConstant.PUBLIC_KEY);
map.put("hash", Utils.MD5String("1" + GlobalConstant.PRIVATE_KEY + GlobalConstant.PUBLIC_KEY));
Utils.hideKeyboard(this);
new ParseController(this, ParseController.HttpMethod.GET, map,
true, getResources().getString(R.string.loading),
new AsyncTaskCompleteListener() {
@Override
public void onSuccess(String response) {
try {
JSONObject objMain = new JSONObject(response);
String code = objMain.getString("code");
if (code.equals("200")) {
JSONObject objData = objMain.getJSONObject("data");
JSONArray jsonArray = objData.getJSONArray("results");
if (jsonArray.length() > 0) {
comicList.clear();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
JSONObject objectThumbnail = object.getJSONObject("thumbnail");
//
HashMap<String, String> hashMap = new HashMap<>();
String path = objectThumbnail.getString("path");
String extension = objectThumbnail.getString("extension");
hashMap.put("image_path", path + "." + extension);
comicList.add(hashMap);
}
setData();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailed(int statusCode, String msg) {
Utils.showToast(MainActivity.this, msg);
}
});
}
private void setData() {
grid_view.setAdapter(new GridViewAdapter(this, comicList));
}
}
GridViewAdapter
package com.zt.marvelapiintegration.activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.zt.marvelapiintegration.R;
import java.util.ArrayList;
import java.util.HashMap;
public class GridViewAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<HashMap<String, String>> imageList;
private DisplayImageOptions options;
public GridViewAdapter(Context context, ArrayList<HashMap<String, String>> list) {
mContext = context;
imageList = list;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.mipmap.ic_launcher)
.showImageForEmptyUri(R.mipmap.ic_launcher)
.showImageOnFail(R.mipmap.ic_launcher)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.build();
}
@Override
public int getCount() {
return imageList.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = new View(mContext);
view = inflater.inflate(R.layout.row_gridview, null);
ImageView img_row = view.findViewById(R.id.img_row);
String picturePath = imageList.get(position).get("image_path");
ImageLoader.getInstance().displayImage(picturePath, img_row, options);
} else {
view = convertView;
}
return view;
}
}
AsyncTaskCompleteListener
package com.zt.marvelapiintegration.restapicall;
public interface AsyncTaskCompleteListener {
void onSuccess(String response);
void onFailed(int statusCode, String msg);
}
ParseController
package com.zt.marvelapiintegration.restapicall;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import com.zt.marvelapiintegration.global.Utils;
import java.io.File;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import okhttp3.ConnectionPool;
import okhttp3.ConnectionSpec;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.TlsVersion;
public class ParseController {
private Map<String, String> map;
private Context activity;
private AsyncTaskCompleteListener listener = null;
private String strURL;
private boolean isShowLoading;
private String loadingMsg;
private HttpMethod httpMethod;
private static String strInternet = "Internet Connection is not available";
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/jpg");
private static final int TIMEOUT = 15 * 60 * 1000;
private int statusCode = 0;
public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
try {
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, null);
client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.build();
List<ConnectionSpec> specs = new ArrayList<>();
specs.add(cs);
specs.add(ConnectionSpec.COMPATIBLE_TLS);
specs.add(ConnectionSpec.CLEARTEXT);
client.connectionSpecs(specs);
} catch (Exception exc) {
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
}
}
return client;
}
protected static OkHttpClient configureHttpClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.cache(null)
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.retryOnConnectionFailure(true).
connectionPool(new ConnectionPool(0, 1, TimeUnit.NANOSECONDS));
return enableTls12OnPreLollipop(builder).build();
}
public enum HttpMethod {
GET,
POST,
PUT,
DELETE,
FILEUPLOAD
}
// ParseController constructor,get all parameter via map,checking internet
// connection
public ParseController(Context act, HttpMethod method,
Map<String, String> map, boolean isShowLoading, String loadingMsg,
AsyncTaskCompleteListener listener) {
this.map = map;
this.httpMethod = method;
this.activity = act;
this.listener = listener;
this.isShowLoading = isShowLoading;
this.loadingMsg = loadingMsg;
this.statusCode = 0;
// is Internet Connection Available...
if (Utils.isNetworkAvailable(activity)) {
if (map.containsKey("url")) {
strURL = map.get("url");
map.remove("url");
}
//Multipart body must have at least one part.
if (map.size() == 0) {
map.put("device_type", "android");
}
// getUnsafeOkHttpClient();
new AsyncHttpRequest().execute();
Log.d("TYPE", httpMethod.toString());
} else {
listener.onFailed(100, strInternet);
}
}
// API call via async Task
class AsyncHttpRequest extends AsyncTask<Void, Void, String> {
private ProgressDialog progressDialog = new ProgressDialog(activity);
@Override
protected void onPreExecute() {
super.onPreExecute();
if (activity != null && activity instanceof Activity
&& !((Activity) activity).isFinishing() && isShowLoading) {
progressDialog.setMessage(loadingMsg);
progressDialog.setCancelable(false);
progressDialog.show();
}
}
@Override
protected String doInBackground(Void... params) {
return chooseWebService();
}
@Override
protected void onPostExecute(String result) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
checkResponse(result);
super.onPostExecute(result);
}
}
public String chooseWebService() {
switch (httpMethod) {
case POST:
return callPOSTAPI();
case GET:
return callGETAPI();
case DELETE:
return callDeleteAPI();
case PUT:
return callPUTAPI();
case FILEUPLOAD:
map.put("url", strURL);
return fileVideoAndImageUploading(map, 2);
default:
break;
}
return null;
}
public String callPOSTAPI() {
try {
Request.Builder builder = new Request.Builder();
MultipartBody.Builder multipartBody = new MultipartBody.Builder();
multipartBody.setType(MultipartBody.FORM);
Log.e("STRURL", strURL);
for (String key : map.keySet()) {
Log.e("Params", key + " = " + map.get(key));
multipartBody.addFormDataPart(key, map.get(key));
}
builder.url(strURL);
builder.post(multipartBody.build());
Request request = builder.build();
Response response = configureHttpClient().newCall(request).execute();
statusCode = response.code();
return response.body().string();
} catch (UnknownHostException ex) {
ex.printStackTrace();
return strInternet;
} catch (SocketTimeoutException ex) {
ex.printStackTrace();
return strInternet;
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
return strInternet;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String fileVideoAndImageUploading(Map<String, String> hashMap, int k) {
try {
Request.Builder builder = new Request.Builder();
MultipartBody.Builder multipartBody = new MultipartBody.Builder();
multipartBody.setType(MultipartBody.FORM);
if (hashMap.containsKey("media")) {
String strFilePath = hashMap.get("media");
hashMap.remove("media");
File file = new File(strFilePath);
Log.d("file size", file.length() + "");
if (file != null && file.exists()) {
Log.d("Params >> ", "file_data = " + strFilePath);
multipartBody
.addFormDataPart("profile_photo", file.getName(),
RequestBody.create(MEDIA_TYPE_PNG, file));
} else {
Log.d("file path error", "path not found: " + strFilePath);
}
}
String strUrl = hashMap.get("url");
hashMap.remove("url");
Log.d("STRURL >> ", strUrl);
for (String key : hashMap.keySet()) {
Log.d("Params", key + " = " + hashMap.get(key));
multipartBody.addFormDataPart(key, hashMap.get(key));
}
builder.url(strUrl);
builder.post(multipartBody.build());
Request request = builder.build();
Response response = configureHttpClient().newCall(request).execute();
return response.body().string();
} catch (UnknownHostException ex) {
ex.printStackTrace();
return strInternet;
} catch (SocketTimeoutException ex) {
ex.printStackTrace();
return strInternet;
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
return strInternet;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String callPOSTAPI(Map<String, String> map1) {
try {
Request.Builder builder = new Request.Builder();
MultipartBody.Builder multipartBody = new MultipartBody.Builder();
multipartBody.setType(MultipartBody.FORM);
String strUrl = map1.get("url");
map1.remove("url");
Log.e("STRURL >> ", strUrl);
for (String key : map1.keySet()) {
Log.e("Params", key + " = " + map1.get(key));
multipartBody.addFormDataPart(key, map1.get(key));
}
builder.url(strUrl);
builder.post(multipartBody.build());
Request request = builder.build();
Response response = configureHttpClient().newCall(request).execute();
return response.body().string();
} catch (UnknownHostException ex) {
ex.printStackTrace();
return strInternet;
} catch (SocketTimeoutException ex) {
ex.printStackTrace();
return strInternet;
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
return strInternet;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public String callPUTAPI() {
try {
Request.Builder builder = new Request.Builder();
Log.e("Url in ParseController", strURL);
FormBody.Builder formBody = new FormBody.Builder();
for (String key : map.keySet()) {
Log.e("Params", key + " = " + map.get(key));
formBody.add(key, map.get(key));
}
builder.url(strURL);
builder.put(formBody.build());
Request request = builder.build();
Response response = configureHttpClient().newCall(request).execute();
statusCode = response.code();
return response.body().string();
} catch (UnknownHostException ex) {
ex.printStackTrace();
return strInternet;
} catch (SocketTimeoutException ex) {
ex.printStackTrace();
return strInternet;
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
return strInternet;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public String callGETAPI() {
try {
Log.d("STRURL", strURL);
HttpUrl.Builder httpBuider = HttpUrl.parse(strURL).newBuilder();
for (String key : map.keySet()) {
Log.e("Params", key + " = " + map.get(key));
httpBuider.addQueryParameter(key, map.get(key));
}
Request request = new Request.Builder().url(httpBuider.build()).build();
Response response = configureHttpClient().newCall(request).execute();
statusCode = response.code();
return response.body().string();
} catch (UnknownHostException ex) {
ex.printStackTrace();
return strInternet;
} catch (SocketTimeoutException ex) {
ex.printStackTrace();
return strInternet;
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
return strInternet;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public String callDeleteAPI() {
try {
Request.Builder builder = new Request.Builder();
Log.d("STRURL", strURL);
FormBody.Builder formBody = new FormBody.Builder();
for (String key : map.keySet()) {
Log.d("Params", key + " = " + map.get(key));
formBody.add(key, map.get(key));
}
builder.url(strURL);
builder.delete(formBody.build());
Request request = builder.build();
Response response = configureHttpClient().newCall(request).execute();
statusCode = response.code();
return response.body().string();
} catch (UnknownHostException ex) {
ex.printStackTrace();
return strInternet;
} catch (SocketTimeoutException ex) {
ex.printStackTrace();
return strInternet;
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
return strInternet;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// checking response is null or empty if not null call onTaskCompleted
// method
public void checkResponse(String response) {
if (response == null || TextUtils.isEmpty(response.trim())
|| response.trim().equalsIgnoreCase("null")) {
Log.e("Response in Controller", "Response is null");
listener.onFailed(statusCode, "Response Is Empty Please Try Again Later");
} else {
Log.e("Response in Controller", response.trim());
Log.e("=======", "=================================================================");
listener.onSuccess(response);
}
}
}
SSLCertificateHandler
package com.zt.marvelapiintegration.restapicall;
import android.os.Build;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import okhttp3.ConnectionSpec;
import okhttp3.TlsVersion;
public class SSLCertificateHandler {
protected static final String TAG = "NukeSSLCerts";
/**
* Enables https connections
*/
public static void nuke() {
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
try {
SSLContext sc = SSLContext.getInstance("sslv3");
sc.init(null, null, null);
HttpsURLConnection.setDefaultSSLSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.SSL_3_0)
.build();
List<ConnectionSpec> specs = new ArrayList<>();
specs.add(cs);
specs.add(ConnectionSpec.COMPATIBLE_TLS);
specs.add(ConnectionSpec.CLEARTEXT);
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
} catch (Exception exc) {
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
}
}
/* try {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] myTrustedAnchors = new X509Certificate[0];
return myTrustedAnchors;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
} catch (Exception e) {
}*/
}
}
Tls12SocketFactory
package com.zt.marvelapiintegration.restapicall;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/**
* Enables TLS v1.2 when creating SSLSockets.
* <p/>
* For some reason, android supports TLS v1.2 from API 16, but enables it by
* default only from API 20.
* @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
* @see SSLSocketFactory
*/
public class Tls12SocketFactory extends SSLSocketFactory {
private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
final SSLSocketFactory delegate;
public Tls12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
}
return s;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:fitsSystemWindows="true">
<include layout="@layout/toolbar" />
<GridView
android:id="@+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:horizontalSpacing="20dp"
android:numColumns="3"
android:verticalSpacing="20dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
row_gridview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img_row"
android:layout_width="200dp"
android:layout_height="300dp"
android:scaleType="fitXY" />
</RelativeLayout>
toolbar.xml
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay">
<TextView
android:id="@+id/tv_title"
style="@style/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="colorAccent">@color/colorPrimary</item>
<item name="windowActionBar">true</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="tv_title">
<item name="android:layout_gravity">center</item>
<item name="android:textColor">@color/white</item>
<item name="android:textSize">20sp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textStyle">normal</item>
</style>
</resources>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zt.marvelapiintegration">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".global.GlobalApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.zt.marvelapiintegration"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
/*Support Design */
implementation 'com.android.support:design:27+'
/* MultiDex */
implementation 'com.android.support:multidex:1.0.1'
/* HTTP call for webservice */
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
/* Universal Image Loader */
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
}