diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9c4de58
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..00cf481
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README_ABT_APP.md b/README_ABT_APP.md
new file mode 100644
index 0000000..32a4aca
--- /dev/null
+++ b/README_ABT_APP.md
@@ -0,0 +1,35 @@
+# ShowCaseAndroidApp #
+
+This application gets a list of devices and the android versions and displays them accordingly.
+It allows users to be able to add new android versions to the list and also add new devices with a limitation to not being able to add images to the devices.
+
+It has the following features:
+- Add a device
+- Add an android version
+- Delete a device
+- Delete an android version
+- Get a list of devices and android versions
+- View device details
+
+Pull to refresh allows new data to get synced with the existing data. There is a database storage that allows data to be fetched from it with the capability of syncing only the latest entries using pull to refresh
+
+# How to get setup #
+
+Android Studio v2.0 Preview 4 has been used for this application, however, you can use any earlier version of Android Studio. JDK 1.8 and JDK 1.7 can be used.
+- Install JDK and any version of Android Studio
+- Clone this repository or else download the application by Selecting import from VCS (GitHub being an option)
+- Build the project
+- You will find the apk in the folder /app/build/outputs/apk/
+
+# Libraries used #
+The following libraries have been used in this application
+- AppCompat v7:23.1.1
+- GSON
+- Squareup OK HTTP
+- Retrofit v2.0.0-beta2
+- Retrofit GSON Converter
+- MaterialEditText
+- SwipeLayout
+- Android Support v4
+- FloatingActionButton
+- CardView
\ No newline at end of file
diff --git a/ShowCaseAndroidApp.iml b/ShowCaseAndroidApp.iml
new file mode 100644
index 0000000..d141a98
--- /dev/null
+++ b/ShowCaseAndroidApp.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..6933e19
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1,3 @@
+/build/generated
+/build/intermediates
+/build/tmp
diff --git a/app/app.iml b/app/app.iml
new file mode 100644
index 0000000..3fc4f6f
--- /dev/null
+++ b/app/app.iml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..db02160
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,39 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 23
+ buildToolsVersion "23.0.1"
+
+ defaultConfig {
+ applicationId "com.dharashah.showcaseandroidapp"
+ minSdkVersion 14
+ targetSdkVersion 23
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+}
+
+dependencies {
+ compile fileTree(include: ['*.jar'], dir: 'libs')
+ compile 'com.android.support:appcompat-v7:23.1.1'
+ compile 'com.google.code.gson:gson:2.2.4'
+ compile 'com.squareup.okhttp:okhttp:2.0.0'
+ compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
+ compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
+ compile 'com.rengwuxian.materialedittext:library:2.1.4'
+ compile 'com.mcxiaoke.volley:library:1.0.19'
+ compile 'com.daimajia.swipelayout:library:1.2.0'
+ compile 'com.android.support:support-v4:23.1.1'
+ compile 'com.getbase:floatingactionbutton:1.10.1'
+ compile 'com.android.support:cardview-v7:23.1.1'
+}
diff --git a/app/build/outputs/apk/app-debug-unaligned.apk b/app/build/outputs/apk/app-debug-unaligned.apk
new file mode 100644
index 0000000..bc554ad
Binary files /dev/null and b/app/build/outputs/apk/app-debug-unaligned.apk differ
diff --git a/app/build/outputs/apk/app-debug.apk b/app/build/outputs/apk/app-debug.apk
new file mode 100644
index 0000000..2474897
Binary files /dev/null and b/app/build/outputs/apk/app-debug.apk differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..932d9f6
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in E:\Dhara\Android Sdks/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/app/src/androidTest/java/com/dharashah/showcaseandroidapp/ApplicationTest.java b/app/src/androidTest/java/com/dharashah/showcaseandroidapp/ApplicationTest.java
new file mode 100644
index 0000000..df8a593
--- /dev/null
+++ b/app/src/androidTest/java/com/dharashah/showcaseandroidapp/ApplicationTest.java
@@ -0,0 +1,13 @@
+package com.dharashah.showcaseandroidapp;
+
+import android.app.Application;
+import android.test.ApplicationTestCase;
+
+/**
+ * Testing Fundamentals
+ */
+public class ApplicationTest extends ApplicationTestCase {
+ public ApplicationTest() {
+ super(Application.class);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..d2f6ac0
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/ShowCaseApp.java b/app/src/main/java/com/dharashah/showcaseandroidapp/ShowCaseApp.java
new file mode 100644
index 0000000..65c9343
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/ShowCaseApp.java
@@ -0,0 +1,26 @@
+package com.dharashah.showcaseandroidapp;
+
+import android.app.Application;
+import android.content.Context;
+
+/**
+ * Created by USER on 21-01-2016.
+ */
+public class ShowCaseApp extends Application {
+ private static ShowCaseApp mApp;
+ private static Context mContext;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mApp= this;
+ mContext = this;
+ }
+
+ public static ShowCaseApp getAppContext(){
+ if(mApp == null) {
+ mApp = (ShowCaseApp)mContext;
+ }
+ return mApp;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/activity/AddDeviceActivity.java b/app/src/main/java/com/dharashah/showcaseandroidapp/activity/AddDeviceActivity.java
new file mode 100644
index 0000000..5cda7e6
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/activity/AddDeviceActivity.java
@@ -0,0 +1,233 @@
+package com.dharashah.showcaseandroidapp.activity;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.Toolbar;
+import android.text.InputFilter;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.ShowCaseApp;
+import com.dharashah.showcaseandroidapp.adapter.AndroidVersionsAdapter;
+import com.dharashah.showcaseandroidapp.db.DBHelper;
+import com.dharashah.showcaseandroidapp.model.AndroidHistory;
+import com.dharashah.showcaseandroidapp.model.Devices;
+import com.dharashah.showcaseandroidapp.network.RestClient;
+import com.dharashah.showcaseandroidapp.utility.CustomInputValidator;
+import com.rengwuxian.materialedittext.MaterialEditText;
+
+import java.util.List;
+
+import retrofit.Call;
+import retrofit.Callback;
+import retrofit.Response;
+import retrofit.Retrofit;
+
+/**
+ * Created by Dhara Shah on 22/01/2016.
+ */
+public class AddDeviceActivity extends BaseActivity implements View.OnClickListener, View.OnFocusChangeListener {
+ private MaterialEditText mEtDeviceName;
+ private MaterialEditText mEtDeviceDesc;
+ private MaterialEditText mEtAndroidVersion;
+ private LinearLayout mLinDeviceName;
+ private LinearLayout mLinDeviceDesc;
+ private LinearLayout mLinAndroidVersion;
+ private DBHelper mDbHelper;
+ private int mAndroidVersionId;
+ private Toolbar mToolbar;
+ private TextView mTxtTitle;
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.slide_in_down, R.anim.slide_out_down);
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_add_device);
+ initToolbar();
+ initView();
+ }
+
+ private void initToolbar() {
+ mToolbar = (Toolbar)findViewById(R.id.toolbar);
+ setSupportActionBar(mToolbar);
+ mTxtTitle = (TextView)findViewById(R.id.txtTitle);
+ mToolbar.setNavigationIcon(R.drawable.abc_ic_clear_mtrl_alpha);
+ mTxtTitle.setText("Add Device");
+ mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onBackPressed();
+ }
+ });
+ }
+
+ private void initView() {
+ mEtDeviceName = (MaterialEditText)findViewById(R.id.etDeviceName);
+ mEtDeviceDesc = (MaterialEditText)findViewById(R.id.etDeviceDescription);
+ mEtAndroidVersion = (MaterialEditText)findViewById(R.id.etAndroidVersion);
+ mLinDeviceName = (LinearLayout)findViewById(R.id.linDeviceName);
+ mLinDeviceDesc = (LinearLayout)findViewById(R.id.linDeviceDescription);
+ mLinAndroidVersion = (LinearLayout)findViewById(R.id.linAndroidVersion);
+
+ mEtAndroidVersion.setOnClickListener(this);
+
+ mEtDeviceName.addTextChangedListener(new CustomInputValidator(mEtDeviceName));
+ mEtDeviceName.setOnFocusChangeListener(AddDeviceActivity.this);
+
+ mEtDeviceDesc.setFilters(new InputFilter[]{new InputFilter.LengthFilter(256)});
+ mEtDeviceDesc.addTextChangedListener(new CustomInputValidator(mEtDeviceDesc));
+ mEtDeviceDesc.setOnFocusChangeListener(AddDeviceActivity.this);
+
+ mDbHelper = DBHelper.getInstance(ShowCaseApp.getAppContext());
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.etAndroidVersion:
+ bindAndroidVersions();
+ break;
+ }
+ }
+
+ /**
+ * Binds the android versions to the dropdrown pop up view
+ */
+ private void bindAndroidVersions() {
+ hideToolTip();
+ final Dialog dialog = new Dialog(AddDeviceActivity.this);
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ dialog.setContentView(R.layout.pop_up_android_versions);
+ final ListView list = (ListView) dialog.findViewById(R.id.list);
+ list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+
+ final List androidVersionList = mDbHelper.getAndroidVersions(" ASC ");
+ AndroidVersionsAdapter adapter =
+ new AndroidVersionsAdapter(ShowCaseApp.getAppContext(),
+ R.layout.individual_row_android_versions, androidVersionList);
+ list.setAdapter(adapter);
+ list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ list.setPressed(true);
+ dialog.dismiss();
+ mAndroidVersionId = androidVersionList.get(position).getAndroidId();
+ mEtAndroidVersion.setText(androidVersionList.get(position).getName());
+ getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
+ }
+ });
+ dialog.setCancelable(true);
+ dialog.show();
+ }
+
+ private void hideToolTip() {
+ mLinAndroidVersion.setVisibility(View.GONE);
+ mLinDeviceDesc.setVisibility(View.GONE);
+ mLinDeviceName.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ switch (v.getId()) {
+ case R.id.etDeviceName:
+ if(hasFocus) {
+ mLinDeviceName.setVisibility(View.VISIBLE);
+ }else {
+ mLinDeviceName.setVisibility(View.GONE);
+ }
+ break;
+
+ case R.id.etDeviceDescription:
+ if(hasFocus) {
+ mLinDeviceDesc.setVisibility(View.VISIBLE);
+ }else {
+ mLinDeviceDesc.setVisibility(View.GONE);
+ }
+ break;
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.menu_add_device, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_done) {
+ // save to the db and also save to the server
+ validateSubmit();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void validateSubmit() {
+ hideToolTip();
+
+ if(CustomInputValidator.checkError(mEtDeviceName))
+ return;
+ if(CustomInputValidator.checkError(mEtDeviceDesc))
+ return;
+ if(CustomInputValidator.checkError(mEtAndroidVersion))
+ return;
+
+ Devices device = new Devices();
+ device.setAndroidId(mAndroidVersionId);
+ device.setDeviceDesc(mEtDeviceDesc.getText().toString().trim());
+ device.setDeviceName(mEtDeviceName.getText().toString().trim());
+ device.setImageURL("");
+
+ if(RestClient.isNetworkAvailable()) {
+ mDbHelper.insertNewDevice(device);
+
+ Call call = new RestClient().getApiService().addDevice(device);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Response response, Retrofit retrofit) {
+ if(response.errorBody()==null){
+ Toast.makeText(ShowCaseApp.getAppContext(),
+ "Device added successfully!",Toast.LENGTH_LONG).show();
+ onBackPressed();
+ }
+
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+
+ }
+ });
+ }else {
+ Toast.makeText(ShowCaseApp.getAppContext(),
+ ShowCaseApp.getAppContext().getResources().getString(R.string.no_internet),
+ Toast.LENGTH_LONG).show();
+
+ }
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/activity/AddVersionActivity.java b/app/src/main/java/com/dharashah/showcaseandroidapp/activity/AddVersionActivity.java
new file mode 100644
index 0000000..4a51d02
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/activity/AddVersionActivity.java
@@ -0,0 +1,226 @@
+package com.dharashah.showcaseandroidapp.activity;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.ShowCaseApp;
+import com.dharashah.showcaseandroidapp.db.DBHelper;
+import com.dharashah.showcaseandroidapp.model.AndroidHistory;
+import com.dharashah.showcaseandroidapp.network.RestClient;
+import com.dharashah.showcaseandroidapp.utility.CustomInputValidator;
+import com.rengwuxian.materialedittext.MaterialEditText;
+
+import retrofit.Call;
+import retrofit.Callback;
+import retrofit.Response;
+import retrofit.Retrofit;
+
+/**
+ * Created by user on 22/01/2016.
+ */
+public class AddVersionActivity extends BaseActivity implements View.OnFocusChangeListener {
+ private MaterialEditText mEtAndroidName;
+ private MaterialEditText mEtAndroidCodeName;
+ private MaterialEditText mEtAndroidVersion;
+ private MaterialEditText mEtDistribution;
+ private MaterialEditText mEtTarget;
+ private LinearLayout mLinAndroidName;
+ private LinearLayout mLinAndroidCodeName;
+ private LinearLayout mLinAndroidVersion;
+ private LinearLayout mLinTarget;
+ private LinearLayout mLinDistribution;
+ private DBHelper mDbHelper;
+ private Toolbar mToolbar;
+ private TextView mTxtTitle;
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.slide_in_down, R.anim.slide_out_down);
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_add_history);
+ initToolbar();
+ initView();
+ }
+
+ private void initToolbar() {
+ mToolbar = (Toolbar)findViewById(R.id.toolbar);
+ setSupportActionBar(mToolbar);
+ mTxtTitle = (TextView)findViewById(R.id.txtTitle);
+ mTxtTitle.setText("Add Android Version");
+ mToolbar.setNavigationIcon(R.drawable.abc_ic_clear_mtrl_alpha);
+ mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onBackPressed();
+ }
+ });
+ }
+
+ private void initView() {
+ mEtAndroidName = (MaterialEditText)findViewById(R.id.etAndroidName);
+ mEtAndroidCodeName = (MaterialEditText)findViewById(R.id.etAndroidCodeName);
+ mEtAndroidVersion = (MaterialEditText)findViewById(R.id.etAndroidVersion);
+ mEtDistribution = (MaterialEditText)findViewById(R.id.etDistribution);
+ mEtTarget = (MaterialEditText)findViewById(R.id.etAndroidTarget);
+
+ mLinAndroidName = (LinearLayout)findViewById(R.id.linAndroidName);
+ mLinAndroidCodeName = (LinearLayout)findViewById(R.id.linAndroidCodeName);
+ mLinAndroidVersion = (LinearLayout)findViewById(R.id.linAndroidVersion);
+ mLinTarget = (LinearLayout)findViewById(R.id.linAndroidTarget);
+ mLinDistribution = (LinearLayout)findViewById(R.id.linDistribution);
+
+ mEtAndroidName.addTextChangedListener(new CustomInputValidator(mEtAndroidName));
+ mEtAndroidName.setOnFocusChangeListener(AddVersionActivity.this);
+
+ mEtAndroidCodeName.addTextChangedListener(new CustomInputValidator(mEtAndroidCodeName));
+ mEtAndroidCodeName.setOnFocusChangeListener(AddVersionActivity.this);
+
+ mEtAndroidVersion.addTextChangedListener(new CustomInputValidator(mEtAndroidVersion));
+ mEtAndroidVersion.setOnFocusChangeListener(AddVersionActivity.this);
+
+ mEtTarget.addTextChangedListener(new CustomInputValidator(mEtTarget));
+ mEtTarget.setOnFocusChangeListener(AddVersionActivity.this);
+
+ mEtDistribution.addTextChangedListener(new CustomInputValidator(mEtDistribution));
+ mEtDistribution.setOnFocusChangeListener(AddVersionActivity.this);
+
+ mDbHelper = DBHelper.getInstance(ShowCaseApp.getAppContext());
+ }
+
+ private void hideToolTip() {
+ mLinAndroidVersion.setVisibility(View.GONE);
+ mLinAndroidCodeName.setVisibility(View.GONE);
+ mLinAndroidName.setVisibility(View.GONE);
+ mLinTarget.setVisibility(View.GONE);
+ mLinDistribution.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ switch (v.getId()) {
+ case R.id.etAndroidName:
+ if(hasFocus) {
+ mLinAndroidName.setVisibility(View.VISIBLE);
+ }else {
+ mLinAndroidName.setVisibility(View.GONE);
+ }
+ break;
+
+ case R.id.etAndroidCodeName:
+ if(hasFocus) {
+ mLinAndroidCodeName.setVisibility(View.VISIBLE);
+ }else {
+ mLinAndroidCodeName.setVisibility(View.GONE);
+ }
+ break;
+
+ case R.id.etAndroidVersion:
+ if(hasFocus) {
+ mLinAndroidVersion.setVisibility(View.VISIBLE);
+ }else {
+ mLinAndroidVersion.setVisibility(View.GONE);
+ }
+ break;
+
+ case R.id.etAndroidTarget:
+ if(hasFocus) {
+ mLinTarget.setVisibility(View.VISIBLE);
+ }else {
+ mLinTarget.setVisibility(View.GONE);
+ }
+ break;
+
+ case R.id.etDistribution:
+ if(hasFocus) {
+ mLinDistribution.setVisibility(View.VISIBLE);
+ }else {
+ mLinDistribution.setVisibility(View.GONE);
+ }
+ break;
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.menu_add_device, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_done) {
+ // save to the db and also save to the server
+ validateSubmit();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void validateSubmit() {
+ hideToolTip();
+
+ if(CustomInputValidator.checkError(mEtAndroidName))
+ return;
+ if(CustomInputValidator.checkError(mEtAndroidCodeName))
+ return;
+ if(CustomInputValidator.checkError(mEtAndroidVersion))
+ return;
+ if(CustomInputValidator.checkError(mEtTarget))
+ return;
+ if(CustomInputValidator.checkError(mEtDistribution))
+ return;
+
+ AndroidHistory history = new AndroidHistory();
+ history.setCodeName(mEtAndroidCodeName.getText().toString().trim());
+ history.setTarget(mEtTarget.getText().toString().trim());
+ history.setDistribution(mEtDistribution.getText().toString().trim() + "%");
+ history.setVersion(mEtAndroidVersion.getText().toString().trim());
+
+ if(RestClient.isNetworkAvailable()) {
+ Call call = new RestClient().getApiService().addAndroidVersion(history);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Response response, Retrofit retrofit) {
+ if(response.errorBody()==null){
+ Toast.makeText(ShowCaseApp.getAppContext(),
+ "Android version added successfully!",Toast.LENGTH_LONG).show();
+ onBackPressed();
+ }
+
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+
+ }
+ });
+
+ mDbHelper.insertAndroidVersion(history);
+ }else {
+ Toast.makeText(ShowCaseApp.getAppContext(),
+ ShowCaseApp.getAppContext().getResources().getString(R.string.no_internet),
+ Toast.LENGTH_LONG).show();
+ }
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/activity/BaseActivity.java b/app/src/main/java/com/dharashah/showcaseandroidapp/activity/BaseActivity.java
new file mode 100644
index 0000000..da94941
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/activity/BaseActivity.java
@@ -0,0 +1,20 @@
+package com.dharashah.showcaseandroidapp.activity;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+
+import com.dharashah.showcaseandroidapp.utility.CustomExceptionHandler;
+
+/**
+ * Created by user on 22/01/2016.
+ */
+public class BaseActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
+ Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
+ }
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/activity/MainActivity.java b/app/src/main/java/com/dharashah/showcaseandroidapp/activity/MainActivity.java
new file mode 100644
index 0000000..0db3366
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/activity/MainActivity.java
@@ -0,0 +1,191 @@
+package com.dharashah.showcaseandroidapp.activity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.ShowCaseApp;
+import com.dharashah.showcaseandroidapp.callback.ILoadListener;
+import com.dharashah.showcaseandroidapp.db.DBHelper;
+import com.dharashah.showcaseandroidapp.fragment.AndroidHistoryFragment;
+import com.dharashah.showcaseandroidapp.fragment.DeviceFragment;
+import com.dharashah.showcaseandroidapp.model.AllData;
+import com.dharashah.showcaseandroidapp.network.RestClient;
+import com.getbase.floatingactionbutton.FloatingActionButton;
+import com.getbase.floatingactionbutton.FloatingActionsMenu;
+
+import retrofit.Call;
+import retrofit.Callback;
+import retrofit.Response;
+import retrofit.Retrofit;
+
+
+public class MainActivity extends BaseActivity implements View.OnClickListener, Callback{
+ private Button mBtnDevices;
+ private Button mBtnHistory;
+ private AndroidHistoryFragment mHistoryFragment;
+ private DBHelper mDBHelper;
+ private DeviceFragment mDeviceFragment;
+ private Callback mCallback;
+ private FloatingActionButton fabAddDevice;
+ private FloatingActionButton fabAddVersion;
+ private FloatingActionsMenu fabMenu;
+ private ILoadListener mLoadListener;
+ private Toolbar mToolbar;
+ private TextView mTxtTitle;
+
+ public void setLoadListener(ILoadListener loadListener) {
+ this.mLoadListener = loadListener;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ initToolbar();
+ initView();
+ initFragment();
+ initServiceCalls();
+ }
+
+ private void initToolbar() {
+ mTxtTitle = (TextView)findViewById(R.id.txtTitle);
+ mToolbar=(Toolbar)findViewById(R.id.toolbar);
+ mTxtTitle.setText("Dashboard");
+ setSupportActionBar(mToolbar);
+ }
+
+ private void initView() {
+ mCallback = this;
+ mBtnHistory = (Button)findViewById(R.id.btnAndroidVersions);
+ mBtnDevices = (Button)findViewById(R.id.btnAndroidDevices);
+ fabAddDevice = (FloatingActionButton)findViewById(R.id.fabAndroidDevice);
+ fabAddVersion = (FloatingActionButton)findViewById(R.id.fabAndroidHistory);
+ fabMenu =(FloatingActionsMenu)findViewById(R.id.fabMenu);
+
+ mBtnDevices.setOnClickListener(this);
+ mBtnHistory.setOnClickListener(this);
+ fabAddVersion.setOnClickListener(this);
+ fabAddDevice.setOnClickListener(this);
+
+ mDBHelper = DBHelper.getInstance(ShowCaseApp.getAppContext());
+
+ }
+
+ @Override
+ public void onClick(View v) {
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ switch (v.getId()) {
+ case R.id.btnAndroidDevices:
+ if(mHistoryFragment != null) {
+ mHistoryFragment.onPause();
+ }
+
+ if(mDeviceFragment == null) {
+ mDeviceFragment = DeviceFragment.newInstance();
+ }
+
+ ft.replace(R.id.content_frame, mDeviceFragment);
+ break;
+
+ case R.id.btnAndroidVersions:
+ if(mDeviceFragment != null) {
+ mDeviceFragment.onPause();
+ }
+
+ if(mHistoryFragment == null) {
+ mHistoryFragment = AndroidHistoryFragment.newInstance();
+ }
+
+ ft.replace(R.id.content_frame, mHistoryFragment);
+ break;
+
+ case R.id.fabAndroidDevice:
+ fabMenu.collapse();
+ Intent intent = new Intent(ShowCaseApp.getAppContext(), AddDeviceActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.slide_in_up, R.anim.slide_out_up);
+ break;
+
+ case R.id.fabAndroidHistory:
+ fabMenu.collapse();
+ intent = new Intent(ShowCaseApp.getAppContext(), AddVersionActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.slide_in_up, R.anim.slide_out_up);
+ break;
+ }
+ ft.commit();
+ }
+
+ private void initFragment() {
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ mDeviceFragment = DeviceFragment.newInstance();
+ ft.replace(R.id.content_frame, mDeviceFragment);
+ ft.commit();
+ }
+
+ private void initServiceCalls() {
+ boolean hasData = mDBHelper.hasData();
+
+ // we have data here
+ if(hasData) {
+ if(mLoadListener != null) {
+ // do not do anything
+ // load the data into the fragment first selected
+ mLoadListener.onLoadData();
+ }
+ }else {
+ if(RestClient.isNetworkAvailable()) {
+ Call call = new RestClient().getApiService().getAllData();
+ call.enqueue(mCallback);
+ }else {
+ Toast.makeText(ShowCaseApp.getAppContext(),
+ ShowCaseApp.getAppContext().getResources().getString(R.string.no_internet),Toast.LENGTH_LONG).show();
+ }
+ }
+ }
+
+ @Override
+ public void onResponse(Response response, Retrofit retrofit) {
+ if(response.body() != null) {
+ addDataToDatabase(response.body());
+ }
+
+ if(mLoadListener != null) {
+ mLoadListener.onRefreshData(response.body());
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+
+ }
+
+ /**
+ * Start threads to add data to the database
+ * @param response
+ */
+ private void addDataToDatabase(final AllData response) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ mDBHelper.addDevices(response.getDeviceList());
+ mLoadListener.onLoadData();
+ }
+ }).start();
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ mDBHelper.addVersions(response.getAndroidHistoryList());
+ mLoadListener.onLoadData();
+ }
+ }).start();
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/AndroidVersionsAdapter.java b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/AndroidVersionsAdapter.java
new file mode 100644
index 0000000..8fba059
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/AndroidVersionsAdapter.java
@@ -0,0 +1,68 @@
+package com.dharashah.showcaseandroidapp.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.model.AndroidHistory;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Created by Dhara Shah on 22/01/2016.
+ */
+public class AndroidVersionsAdapter extends ArrayAdapter {
+ private Context mContext;
+ private List mList;
+ private int RESOURCE;
+
+ public AndroidVersionsAdapter(Context context, int resource, List objects) {
+ super(context, resource, objects);
+ mContext = context;
+ mList = objects;
+ RESOURCE = resource;
+
+ Collections.sort(mList, new Comparator() {
+ @Override
+ public int compare(AndroidHistory lhs, AndroidHistory rhs) {
+ if (rhs.getAndroidId() > lhs.getAndroidId()) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+ });
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View view = convertView;
+ ViewHolder vh = null;
+ if(view == null) {
+ view = LayoutInflater.from(mContext).inflate(RESOURCE, parent,false);
+ vh = new ViewHolder();
+ vh.txtAndroidVersion = (TextView)view.findViewById(R.id.txtAndroidVersion);
+ vh.txtAndroidVersionName = (TextView)view.findViewById(R.id.txtAndroidVersionName);
+ view.setTag(vh);
+ }else {
+ vh = (ViewHolder)view.getTag();
+ }
+
+ AndroidHistory history = mList.get(position);
+ vh.txtAndroidVersion.setText(history.getVersion());
+ vh.txtAndroidVersionName.setText(history.getName());
+
+ return view;
+ }
+
+ class ViewHolder {
+ TextView txtAndroidVersionName;
+ TextView txtAndroidVersion;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/DeviceAdapter.java b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/DeviceAdapter.java
new file mode 100644
index 0000000..832b62c
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/DeviceAdapter.java
@@ -0,0 +1,97 @@
+package com.dharashah.showcaseandroidapp.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.daimajia.swipe.SwipeLayout;
+import com.daimajia.swipe.adapters.BaseSwipeAdapter;
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.callback.IDataFunctionListener;
+import com.dharashah.showcaseandroidapp.model.Devices;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Created by USER on 22-01-2016.
+ */
+public class DeviceAdapter extends BaseSwipeAdapter {
+ private Context mContext;
+ private List mDeviceList;
+ private IDataFunctionListener mListener;
+
+ public DeviceAdapter(Context context, List objects, IDataFunctionListener listener) {
+ mContext = context;
+ mDeviceList = objects;
+ mListener = listener;
+
+ Collections.sort(mDeviceList, new Comparator() {
+ @Override
+ public int compare(Devices lhs, Devices rhs) {
+ if(lhs.getDeviceId() > rhs.getDeviceId()) {
+ return 1;
+ }else {
+ return -1;
+ }
+ }
+ });
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return super.getItemViewType(position);
+ }
+
+ @Override
+ public int getSwipeLayoutResourceId(int position) {
+ return R.id.swipe;
+ }
+
+ @Override
+ public View generateView(int position, ViewGroup parent) {
+ return LayoutInflater.from(mContext).inflate(R.layout.individual_swipe_row, parent, false);
+ }
+
+ @Override
+ public void fillValues(final int position, View convertView) {
+ final DeviceViewHolder viewHolder = new DeviceViewHolder(convertView);
+ viewHolder.txtDeviceName.setText(mDeviceList.get(position).getDeviceName());
+ viewHolder.txtDeviceDesc.setText(mDeviceList.get(position).getDeviceDesc());
+ viewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.PullOut);
+ viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Right, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper));
+ viewHolder.swipeLayout.getSurfaceView().setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // show the details
+ mListener.onDisplaySelected(mDeviceList.get(position));
+ }
+ });
+ viewHolder.relDelete.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(mListener != null) mListener.onDeleteSelected(mDeviceList.get(position).getDeviceId());
+ mDeviceList.remove(position);
+ viewHolder.swipeLayout.close(true);
+ notifyDataSetChanged();
+ }
+ });
+ }
+
+ @Override
+ public int getCount() {
+ return mDeviceList.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mDeviceList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/DeviceViewHolder.java b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/DeviceViewHolder.java
new file mode 100644
index 0000000..2112ad0
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/DeviceViewHolder.java
@@ -0,0 +1,41 @@
+package com.dharashah.showcaseandroidapp.adapter;
+
+import android.view.View;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.daimajia.swipe.SwipeLayout;
+import com.dharashah.showcaseandroidapp.R;
+
+/**
+ * Created by user on 23/01/2016.
+ */
+public class DeviceViewHolder {
+ public TextView txtDeviceName;
+ public TextView txtDeviceDesc;
+ public SwipeLayout swipeLayout;
+ public RelativeLayout relDelete;
+
+ public DeviceViewHolder(View view) {
+ swipeLayout = (SwipeLayout) view.findViewById(R.id.swipe);
+ txtDeviceName = (TextView)view.findViewById(R.id.txtDeviceName);
+ txtDeviceDesc = (TextView)view.findViewById(R.id.txtDeviceDesc);
+ relDelete = (RelativeLayout)view.findViewById(R.id.relDelete);
+ }
+
+ public TextView getTxtDeviceName() {
+ return txtDeviceName;
+ }
+
+ public void setTxtDeviceName(TextView txtDeviceName) {
+ this.txtDeviceName = txtDeviceName;
+ }
+
+ public TextView getTxtDeviceDesc() {
+ return txtDeviceDesc;
+ }
+
+ public void setTxtDeviceDesc(TextView txtDeviceDesc) {
+ this.txtDeviceDesc = txtDeviceDesc;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/VersionsAdapter.java b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/VersionsAdapter.java
new file mode 100644
index 0000000..d620bb1
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/VersionsAdapter.java
@@ -0,0 +1,91 @@
+package com.dharashah.showcaseandroidapp.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.daimajia.swipe.SwipeLayout;
+import com.daimajia.swipe.adapters.BaseSwipeAdapter;
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.callback.IDataFunctionListener;
+import com.dharashah.showcaseandroidapp.model.AndroidHistory;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+
+/**
+ * Created by user on 23/01/2016.
+ */
+public class VersionsAdapter extends BaseSwipeAdapter {
+ private LinkedList mHistoryList;
+ private Context mContext;
+ private IDataFunctionListener mListener;
+
+ public VersionsAdapter(Context context, LinkedList list, IDataFunctionListener listener) {
+ mContext = context;
+ mHistoryList = list;
+ mListener = listener;
+
+ Collections.sort(mHistoryList, new Comparator() {
+ @Override
+ public int compare(AndroidHistory lhs, AndroidHistory rhs) {
+ if(lhs.getAndroidId() > rhs.getAndroidId()) {
+ return 1;
+ }else {
+ return -1;
+ }
+ }
+ });
+ }
+
+ @Override
+ public int getSwipeLayoutResourceId(int position) {
+ return R.id.swipe;
+ }
+
+ @Override
+ public View generateView(int position, ViewGroup parent) {
+ return LayoutInflater.from(mContext).inflate(R.layout.individual_swipe_versions, parent, false);
+ }
+
+ @Override
+ public void fillValues(final int position, View convertView) {
+ final VersionsViewHolder viewHolder = new VersionsViewHolder(convertView);
+ viewHolder.txtAndroidName.setText(mHistoryList.get(position).getName());
+ viewHolder.txtAndroidVersionNumber.setText(mHistoryList.get(position).getVersion());
+ viewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.PullOut);
+ viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Right, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper));
+ viewHolder.swipeLayout.getSurfaceView().setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // show the details or lead to another fragment
+ }
+ });
+ viewHolder.relDelete.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mListener.onDeleteSelected(mHistoryList.get(position).getAndroidId());
+ mHistoryList.remove(position);
+ viewHolder.swipeLayout.close(true);
+ notifyDataSetChanged();
+ }
+ });
+ }
+
+ @Override
+ public int getCount() {
+ return mHistoryList.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mHistoryList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/VersionsViewHolder.java b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/VersionsViewHolder.java
new file mode 100644
index 0000000..e006f89
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/adapter/VersionsViewHolder.java
@@ -0,0 +1,25 @@
+package com.dharashah.showcaseandroidapp.adapter;
+
+import android.view.View;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.daimajia.swipe.SwipeLayout;
+import com.dharashah.showcaseandroidapp.R;
+
+/**
+ * Created by user on 23/01/2016.
+ */
+public class VersionsViewHolder {
+ public TextView txtAndroidVersionNumber;
+ public TextView txtAndroidName;
+ public SwipeLayout swipeLayout;
+ public RelativeLayout relDelete;
+
+ public VersionsViewHolder(View view) {
+ swipeLayout = (SwipeLayout) view.findViewById(R.id.swipe);
+ txtAndroidName = (TextView)view.findViewById(R.id.txtAndroidVersionName);
+ txtAndroidVersionNumber = (TextView)view.findViewById(R.id.txtAndroidVersion);
+ relDelete = (RelativeLayout)view.findViewById(R.id.relDelete);
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/callback/IDataFunctionListener.java b/app/src/main/java/com/dharashah/showcaseandroidapp/callback/IDataFunctionListener.java
new file mode 100644
index 0000000..59d3e85
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/callback/IDataFunctionListener.java
@@ -0,0 +1,9 @@
+package com.dharashah.showcaseandroidapp.callback;
+
+/**
+ * Created by user on 23/01/2016.
+ */
+public interface IDataFunctionListener {
+ void onDeleteSelected(int id);
+ void onDisplaySelected(Object object);
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/callback/ILoadListener.java b/app/src/main/java/com/dharashah/showcaseandroidapp/callback/ILoadListener.java
new file mode 100644
index 0000000..14d8fa4
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/callback/ILoadListener.java
@@ -0,0 +1,11 @@
+package com.dharashah.showcaseandroidapp.callback;
+
+import com.dharashah.showcaseandroidapp.model.AllData;
+
+/**
+ * Created by user on 23/01/2016.
+ */
+public interface ILoadListener {
+ void onLoadData();
+ void onRefreshData(AllData data);
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/db/AndroidVersionContract.java b/app/src/main/java/com/dharashah/showcaseandroidapp/db/AndroidVersionContract.java
new file mode 100644
index 0000000..6508c33
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/db/AndroidVersionContract.java
@@ -0,0 +1,19 @@
+package com.dharashah.showcaseandroidapp.db;
+
+import android.provider.BaseColumns;
+
+/**
+ * Created by user on 21/01/2016.
+ */
+public final class AndroidVersionContract {
+ public AndroidVersionContract(){}
+
+ public static abstract class AndroidVersionEntry implements BaseColumns {
+ public static final String TABLE_NAME = "android_history_master";
+ public static final String COLUMN_NAME_ANDROID_ID = "android_id";
+ public static final String COLUMN_NAME_ANDROID_NAME = "android_name";
+ public static final String COLUMN_NAME_ANDROID_CODE_NAME = "android_code_name";
+ public static final String COLUMN_NAME_ANDROID_TARGET = "android_target";
+ public static final String COLUMN_NAME_ANDROID_DISTRIBUTION = "android_distribution";
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/db/DBHelper.java b/app/src/main/java/com/dharashah/showcaseandroidapp/db/DBHelper.java
new file mode 100644
index 0000000..cf3ec4d
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/db/DBHelper.java
@@ -0,0 +1,282 @@
+package com.dharashah.showcaseandroidapp.db;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import com.dharashah.showcaseandroidapp.model.AndroidHistory;
+import com.dharashah.showcaseandroidapp.model.Devices;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * Created by Dhara Shah on 21/01/2016.
+ */
+public class DBHelper extends SQLiteOpenHelper {
+ private static DBHelper mDbHelper;
+ private static final String DATABASE_NAME = "ShowCaseApp.db";
+ private static final int DATABASE_VERSION = 1;
+
+ private static final String TEXT_TYPE = " TEXT";
+ private static final String INTEGER_TYPE = " INTEGER ";
+ private static final String INTEGER_PRIMARY_KEY = " INTEGER PRIMARY KEY ";
+ private static final String FLOAT_TYPE=" FLOAT ";
+ private static final String COMMA_SEP = ",";
+
+ private static final String CREATE_HISTORY_TABLE =
+ "CREATE TABLE " + AndroidVersionContract.AndroidVersionEntry.TABLE_NAME +
+ "( " + AndroidVersionContract.AndroidVersionEntry._ID + INTEGER_PRIMARY_KEY +
+ COMMA_SEP + AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_ID + INTEGER_TYPE +
+ COMMA_SEP + AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_NAME + TEXT_TYPE +
+ COMMA_SEP + AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_DISTRIBUTION + TEXT_TYPE +
+ COMMA_SEP + AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_CODE_NAME + TEXT_TYPE +
+ COMMA_SEP + AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_TARGET + TEXT_TYPE + ")";
+
+ private static final String CREATE_DEVICE_TABLE =
+ "CREATE TABLE " + DeviceContract.DeviceEntry.TABLE_NAME +
+ " ( " + DeviceContract.DeviceEntry._ID + INTEGER_PRIMARY_KEY +
+ COMMA_SEP + DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_ID + INTEGER_TYPE +
+ COMMA_SEP + DeviceContract.DeviceEntry.COLUMN_NAME_ANDROID_ID + INTEGER_TYPE +
+ COMMA_SEP + DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_NAME + TEXT_TYPE +
+ COMMA_SEP + DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_DESC + TEXT_TYPE +
+ COMMA_SEP + DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_IMAGE + TEXT_TYPE + ")";
+
+ /**
+ * Creates a singleton instance
+ * @param context
+ * @return
+ */
+ public static DBHelper getInstance(Context context) {
+ if(mDbHelper == null) {
+ mDbHelper = new DBHelper(context);
+ }
+ return mDbHelper;
+ }
+
+ public DBHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase sqLiteDatabase) {
+ sqLiteDatabase.execSQL(CREATE_HISTORY_TABLE);
+ sqLiteDatabase.execSQL(CREATE_DEVICE_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
+
+ }
+
+ /**
+ * Inserts a new device to the database
+ * @param device
+ * @return
+ */
+ public long insertNewDevice(Devices device){
+ SQLiteDatabase db = this.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_ID, device.getDeviceId());
+ values.put(DeviceContract.DeviceEntry.COLUMN_NAME_ANDROID_ID, device.getAndroidId());
+ values.put(DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_NAME, device.getDeviceName());
+ values.put(DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_DESC, device.getDeviceDesc());
+ values.put(DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_IMAGE, device.getImageURL());
+ long id = db.insert(DeviceContract.DeviceEntry.TABLE_NAME,null,values );
+ return id;
+ }
+
+ /**
+ * Inserts a new Android Version to the database
+ * @param androidHistory
+ * @return
+ */
+ public long insertAndroidVersion(AndroidHistory androidHistory){
+ SQLiteDatabase db = this.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_ID, androidHistory.getAndroidId());
+ values.put(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_CODE_NAME, androidHistory.getCodeName());
+ values.put(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_DISTRIBUTION, androidHistory.getDistribution());
+ values.put(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_NAME, androidHistory.getName());
+ values.put(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_TARGET, androidHistory.getTarget());
+ long id= db.insert(AndroidVersionContract.AndroidVersionEntry.TABLE_NAME, null, values);
+ return id;
+ }
+
+ /**
+ * Gets the list of android versions
+ * @param sortOrder
+ * @return
+ */
+ public LinkedList getAndroidVersions(String sortOrder) {
+ LinkedList androidHistoryList = new LinkedList<>();
+ SQLiteDatabase db = this.getReadableDatabase();
+ Cursor c = null;
+
+ try {
+ c = db.query(AndroidVersionContract.AndroidVersionEntry.TABLE_NAME,
+ null,
+ null,
+ null,
+ null,
+ null,
+ AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_ID + sortOrder);
+
+ if(c != null && c.moveToFirst()) {
+ do {
+ AndroidHistory history = new AndroidHistory();
+ history.setAndroidId(c.getInt(c.getColumnIndex(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_ID)));
+ history.setName(c.getString(c.getColumnIndex(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_NAME)));
+ history.setCodeName(c.getString
+ (c.getColumnIndex(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_CODE_NAME)));
+ history.setDistribution(c.getString
+ (c.getColumnIndex(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_DISTRIBUTION)));
+ history.setTarget(c.getString
+ (c.getColumnIndex(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_TARGET)));
+ androidHistoryList.add(history);
+ }while(c.moveToNext());
+ }
+ }finally {
+ if(c != null) {
+ c.close();
+ }
+ }
+ return androidHistoryList;
+ }
+
+ /**
+ * Gets the list of devices
+ * @return
+ */
+ public LinkedList getDevices(){
+ LinkedList deviceList = new LinkedList<>();
+ SQLiteDatabase db = this.getReadableDatabase();
+ Cursor c = null;
+
+ try {
+ c = db.query(DeviceContract.DeviceEntry.TABLE_NAME,
+ null,
+ null,
+ null,
+ null,
+ null,
+ DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_ID + " DESC ");
+
+ if(c != null && c.moveToFirst()) {
+ do {
+ Devices device = new Devices();
+ device.setAndroidId(c.getInt(c.getColumnIndex(DeviceContract.DeviceEntry.COLUMN_NAME_ANDROID_ID)));
+ device.setDeviceDesc(c.getString(c.getColumnIndex(DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_DESC)));
+ device.setDeviceId(c.getInt(c.getColumnIndex(DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_ID)));
+ device.setDeviceName(c.getString(c.getColumnIndex(DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_NAME)));
+ device.setImageURL(c.getString(c.getColumnIndex(DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_IMAGE)));
+ deviceList.add(device);
+ }while(c.moveToNext());
+ }
+ }finally {
+ if(c != null) {
+ c.close();
+ }
+ }
+ return deviceList;
+ }
+
+ /**
+ * Checks if there is data in the database
+ * @return
+ */
+ public boolean hasData() {
+ SQLiteDatabase db = this.getReadableDatabase();
+ long countOfDevices = DatabaseUtils.queryNumEntries(db, DeviceContract.DeviceEntry.TABLE_NAME);
+ long countOfVersions = DatabaseUtils.queryNumEntries(db, AndroidVersionContract.AndroidVersionEntry.TABLE_NAME);
+
+ if(countOfDevices <= 0 && countOfVersions <= 0) {
+ return false;
+ }else {
+ return true;
+ }
+ }
+
+ /**
+ * Adds a new device to the database
+ * @param deviceList
+ */
+ public void addDevices(List deviceList) {
+ Stack stack = new Stack<>();
+ stack.addAll(deviceList);
+
+ while(!stack.isEmpty()) {
+ insertNewDevice(stack.pop());
+ }
+ }
+
+ /**
+ * Adds an android version to the database
+ * @param versionList
+ */
+ public void addVersions(List versionList){
+ Stack stack = new Stack<>();
+ stack.addAll(versionList);
+
+ while(!stack.isEmpty()) {
+ insertAndroidVersion(stack.pop());
+ }
+ }
+
+ /**
+ * Gets the android version name to display
+ * @param androidId
+ * @return
+ */
+ public String getVersionName(int androidId) {
+ SQLiteDatabase db =this.getReadableDatabase();
+ Cursor c = null;
+ String androidName = "";
+
+ try {
+ c = db.query(AndroidVersionContract.AndroidVersionEntry.TABLE_NAME,
+ new String[]{AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_NAME},
+ AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_ID + " =?",
+ new String[]{String.valueOf(androidId)},
+ null,
+ null,
+ null);
+
+ if(c != null && c.moveToFirst()) {
+ androidName = c.getString(c.getColumnIndex(AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_NAME));
+ }
+ }finally {
+ if(c != null) {
+ c.close();
+ }
+ }
+
+ return androidName;
+ }
+
+ /**
+ * Delete the device from the database
+ * @param deviceId
+ */
+ public void deleteDevice(int deviceId) {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(DeviceContract.DeviceEntry.TABLE_NAME,
+ DeviceContract.DeviceEntry.COLUMN_NAME_DEVICE_ID + "=?",
+ new String[]{String.valueOf(deviceId)});
+ }
+
+ /**
+ * Delete the android version from the database
+ * @param androidId
+ */
+ public void deleteAndroidVersion(int androidId) {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(AndroidVersionContract.AndroidVersionEntry.TABLE_NAME,
+ AndroidVersionContract.AndroidVersionEntry.COLUMN_NAME_ANDROID_ID + "=?",
+ new String[]{String.valueOf(androidId)});
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/db/DeviceContract.java b/app/src/main/java/com/dharashah/showcaseandroidapp/db/DeviceContract.java
new file mode 100644
index 0000000..2494417
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/db/DeviceContract.java
@@ -0,0 +1,20 @@
+package com.dharashah.showcaseandroidapp.db;
+
+import android.provider.BaseColumns;
+
+/**
+ * Created by user on 21/01/2016.
+ */
+public final class DeviceContract {
+ public DeviceContract(){}
+
+ public static abstract class DeviceEntry implements BaseColumns {
+ public static final String TABLE_NAME = "device_master";
+ public static final String COLUMN_NAME_DEVICE_ID = "device_id";
+ public static final String COLUMN_NAME_DEVICE_NAME = "device_name";
+ public static final String COLUMN_NAME_DEVICE_DESC = "device_desc";
+ public static final String COLUMN_NAME_DEVICE_IMAGE = "device_image";
+ public static final String COLUMN_NAME_ANDROID_ID = "android_id";
+ }
+
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/fragment/AndroidHistoryFragment.java b/app/src/main/java/com/dharashah/showcaseandroidapp/fragment/AndroidHistoryFragment.java
new file mode 100644
index 0000000..1b6c4de
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/fragment/AndroidHistoryFragment.java
@@ -0,0 +1,167 @@
+package com.dharashah.showcaseandroidapp.fragment;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.ShowCaseApp;
+import com.dharashah.showcaseandroidapp.activity.MainActivity;
+import com.dharashah.showcaseandroidapp.adapter.VersionsAdapter;
+import com.dharashah.showcaseandroidapp.callback.IDataFunctionListener;
+import com.dharashah.showcaseandroidapp.callback.ILoadListener;
+import com.dharashah.showcaseandroidapp.db.DBHelper;
+import com.dharashah.showcaseandroidapp.model.AllData;
+import com.dharashah.showcaseandroidapp.model.AndroidHistory;
+import com.dharashah.showcaseandroidapp.network.RestClient;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import retrofit.Call;
+import retrofit.Callback;
+import retrofit.Response;
+import retrofit.Retrofit;
+
+/**
+ * Created by Dhara Shah on 22/01/2016.
+ */
+public class AndroidHistoryFragment extends Fragment implements ILoadListener,
+ SwipeRefreshLayout.OnRefreshListener, Callback>, IDataFunctionListener {
+ private static AndroidHistoryFragment mFragment;
+ private View mView;
+ private ListView mListView;
+ private ILoadListener mListener;
+ private DBHelper mDbHelper;
+ private LinkedList mAndroidHistoryList;
+ private SwipeRefreshLayout mRefreshLayout;
+ private Callback> mCallback;
+ private VersionsAdapter mAdapter;
+ private IDataFunctionListener mDeleteListener;
+
+ public static AndroidHistoryFragment newInstance() {
+ mFragment = new AndroidHistoryFragment();
+ return mFragment;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ mView = inflater.inflate(R.layout.fragment_history, container, false);
+ initView();
+ return mView;
+ }
+
+ private void initView() {
+ mDeleteListener = this;
+ mCallback = this;
+ mListener = this;
+ mDbHelper = DBHelper.getInstance(ShowCaseApp.getAppContext());
+ mListView = (ListView)mView.findViewById(android.R.id.list);
+ mRefreshLayout = (SwipeRefreshLayout)mView.findViewById(R.id.swipeRefreshLayout);
+ mRefreshLayout.setOnRefreshListener(this);
+ mAndroidHistoryList = new LinkedList<>();
+ ((MainActivity)getActivity()).setLoadListener(mListener);
+ mAdapter = new VersionsAdapter(ShowCaseApp.getAppContext(), mAndroidHistoryList, mDeleteListener);
+ mListView.setAdapter(mAdapter);
+ onLoadData();
+ }
+
+ @Override
+ public void onLoadData() {
+ // get data from the database and load here
+ LinkedList histories = mDbHelper.getAndroidVersions(" DESC ");
+ mAndroidHistoryList.clear();
+ mAndroidHistoryList.addAll(histories);
+
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if(mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+ });
+
+ }
+
+ @Override
+ public void onRefreshData(AllData data) {
+ List historyList = data.getAndroidHistoryList();
+ mAndroidHistoryList.clear();
+ mAndroidHistoryList.addAll(historyList);
+
+ if(mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onRefresh() {
+ int startCounter = (mAndroidHistoryList == null) ? 0 : mAndroidHistoryList.size();
+ int endCounter = startCounter + 10;
+
+ if(RestClient.isNetworkAvailable()) {
+ Call> call =
+ new RestClient().getApiService().getAndroidVersions(startCounter, endCounter);
+ call.enqueue(mCallback);
+ }else {
+ mRefreshLayout.setRefreshing(false);
+ }
+ }
+
+ @Override
+ public void onResponse(final Response> response, Retrofit retrofit) {
+ if(response.body() != null) {
+ LinkedList historyList = new LinkedList<>();
+ historyList.addAll(response.body());
+ historyList.addAll(mAndroidHistoryList);
+ mAndroidHistoryList.clear();
+ mAndroidHistoryList.addAll(historyList);
+ if(mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ mDbHelper.addVersions(response.body());
+ }
+ }).start();
+ }
+ mRefreshLayout.setRefreshing(false);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ mRefreshLayout.setRefreshing(false);
+ }
+
+ @Override
+ public void onDeleteSelected(int id) {
+ mDbHelper.deleteAndroidVersion(id);
+
+ Call deleteCall = new RestClient().getApiService().deleteVersion(id);
+ deleteCall.enqueue(new Callback() {
+ @Override
+ public void onResponse(Response response, Retrofit retrofit) {
+
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+
+ }
+ });
+ }
+
+ @Override
+ public void onDisplaySelected(Object object) {
+
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/fragment/DeviceFragment.java b/app/src/main/java/com/dharashah/showcaseandroidapp/fragment/DeviceFragment.java
new file mode 100644
index 0000000..72ed225
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/fragment/DeviceFragment.java
@@ -0,0 +1,202 @@
+package com.dharashah.showcaseandroidapp.fragment;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.ShowCaseApp;
+import com.dharashah.showcaseandroidapp.activity.MainActivity;
+import com.dharashah.showcaseandroidapp.adapter.DeviceAdapter;
+import com.dharashah.showcaseandroidapp.callback.IDataFunctionListener;
+import com.dharashah.showcaseandroidapp.callback.ILoadListener;
+import com.dharashah.showcaseandroidapp.db.DBHelper;
+import com.dharashah.showcaseandroidapp.model.AllData;
+import com.dharashah.showcaseandroidapp.model.Devices;
+import com.dharashah.showcaseandroidapp.network.RestClient;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import retrofit.Call;
+import retrofit.Callback;
+import retrofit.Response;
+import retrofit.Retrofit;
+
+/**
+ * Created by Dhara shah on 22/01/2016.
+ */
+public class DeviceFragment extends Fragment implements ILoadListener, SwipeRefreshLayout.OnRefreshListener, Callback>, IDataFunctionListener {
+ private static DeviceFragment mFragment;
+ private View mView;
+ private ListView mListView;
+ private DBHelper mDbHelper;
+ private ILoadListener mListener;
+ private LinkedList deviceList;
+ private SwipeRefreshLayout mRefreshLayout;
+ private Callback> mCallback;
+ private DeviceAdapter mAdapter;
+ private IDataFunctionListener mDeleteListener;
+
+ public static DeviceFragment newInstance() {
+ mFragment = new DeviceFragment();
+ return mFragment;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ mView = inflater.inflate(R.layout.fragment_devices, container, false);
+ initView();
+ return mView;
+ }
+
+ private void initView() {
+ mListener = this;
+ mDeleteListener = this;
+ mDbHelper = DBHelper.getInstance(ShowCaseApp.getAppContext());
+ mListView = (ListView)mView.findViewById(android.R.id.list);
+ mRefreshLayout = (SwipeRefreshLayout)mView.findViewById(R.id.swipeRefreshLayout);
+ mRefreshLayout.setOnRefreshListener(this);
+ deviceList = new LinkedList<>();
+ ((MainActivity)getActivity()).setLoadListener(mListener);
+ mAdapter = new DeviceAdapter(ShowCaseApp.getAppContext(), deviceList, mDeleteListener);
+ mListView.setAdapter(mAdapter);
+ onLoadData();
+ }
+
+ @Override
+ public void onLoadData() {
+ // get data from the database and load here
+ LinkedList devices = mDbHelper.getDevices();
+ deviceList.clear();
+ deviceList.addAll(devices);
+
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if(mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onRefreshData(AllData data) {
+ List items = data.getDeviceList();
+ deviceList.clear();
+ deviceList.addAll(items);
+
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if(mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onRefresh() {
+ mCallback = this;
+ int startCounter = (deviceList == null) ? 0 : deviceList.size();
+ int endCounter = startCounter + 10;
+
+ if(RestClient.isNetworkAvailable()) {
+ Call> call =
+ new RestClient().getApiService().getDevices(startCounter, endCounter);
+ call.enqueue(mCallback);
+ }else {
+ mRefreshLayout.setRefreshing(false);
+ }
+ }
+
+ @Override
+ public void onResponse(final Response> response, Retrofit retrofit) {
+ if(response.body() != null) {
+ LinkedList deviceListNew = new LinkedList<>();
+ deviceListNew.addAll(response.body());
+ deviceListNew.addAll(deviceList);
+ deviceList.clear();
+ deviceList.addAll(deviceListNew);
+
+ if(mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ mDbHelper.addDevices(response.body());
+ }
+ }).start();
+ }
+
+ mRefreshLayout.setRefreshing(false);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ mRefreshLayout.setRefreshing(false);
+ }
+
+ @Override
+ public void onDeleteSelected(int id) {
+ mDbHelper.deleteDevice(id);
+
+ // make a call to delete the record
+ Call deleteCall = new RestClient().getApiService().deleteDevice(id);
+ deleteCall.enqueue(new Callback() {
+ @Override
+ public void onResponse(Response response, Retrofit retrofit) {
+
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+
+ }
+ });
+ }
+
+ @Override
+ public void onDisplaySelected(Object object) {
+ if(object instanceof Devices) {
+ final Dialog dialog = new Dialog(getActivity());
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ dialog.setContentView(R.layout.pop_up_device_details);
+ TextView txtAndroidVersionName = (TextView)dialog.findViewById(R.id.txtAndroidVersion);
+ TextView txtDeviceName = (TextView)dialog.findViewById(R.id.txtDeviceName);
+ TextView txtDeviceDesc = (TextView)dialog.findViewById(R.id.txtDeviceDesc);
+ ImageView imgClose = (ImageView)dialog.findViewById(R.id.imgClose);
+
+ Devices device = (Devices)object;
+ String androidVersionName = mDbHelper.getVersionName(device.getAndroidId());
+
+ txtAndroidVersionName.setText(androidVersionName);
+ txtDeviceDesc.setText(device.getDeviceDesc());
+ txtDeviceName.setText(device.getDeviceName());
+
+ imgClose.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dialog.dismiss();
+ }
+ });
+
+ dialog.setCancelable(true);
+ dialog.show();
+ }
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/manager/SessionManager.java b/app/src/main/java/com/dharashah/showcaseandroidapp/manager/SessionManager.java
new file mode 100644
index 0000000..6f100ad
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/manager/SessionManager.java
@@ -0,0 +1,7 @@
+package com.dharashah.showcaseandroidapp.manager;
+
+/**
+ * Created by user on 22/01/2016.
+ */
+public class SessionManager {
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/model/AllData.java b/app/src/main/java/com/dharashah/showcaseandroidapp/model/AllData.java
new file mode 100644
index 0000000..c3d6589
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/model/AllData.java
@@ -0,0 +1,31 @@
+package com.dharashah.showcaseandroidapp.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+
+/**
+ * Created by user on 23/01/2016.
+ */
+public class AllData {
+ @SerializedName("android")
+ private List androidHistoryList;
+ @SerializedName("devices")
+ private List deviceList;
+
+ public List getAndroidHistoryList() {
+ return androidHistoryList;
+ }
+
+ public void setAndroidHistoryList(List androidHistoryList) {
+ this.androidHistoryList = androidHistoryList;
+ }
+
+ public List getDeviceList() {
+ return deviceList;
+ }
+
+ public void setDeviceList(List deviceList) {
+ this.deviceList = deviceList;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/model/AndroidHistory.java b/app/src/main/java/com/dharashah/showcaseandroidapp/model/AndroidHistory.java
new file mode 100644
index 0000000..28d31c1
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/model/AndroidHistory.java
@@ -0,0 +1,69 @@
+package com.dharashah.showcaseandroidapp.model;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Created by USER on 21-01-2016.
+ */
+public class AndroidHistory {
+ @SerializedName("id")
+ private int androidId;
+ @SerializedName("name")
+ private String name;
+ @SerializedName("version")
+ private String version;
+ @SerializedName("codename")
+ private String codeName;
+ @SerializedName("target")
+ private String target;
+ @SerializedName("distribution")
+ private String distribution;
+
+ public int getAndroidId() {
+ return androidId;
+ }
+
+ public void setAndroidId(int androidId) {
+ this.androidId = androidId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getCodeName() {
+ return codeName;
+ }
+
+ public void setCodeName(String codeName) {
+ this.codeName = codeName;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public String getDistribution() {
+ return distribution;
+ }
+
+ public void setDistribution(String distribution) {
+ this.distribution = distribution;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/model/Devices.java b/app/src/main/java/com/dharashah/showcaseandroidapp/model/Devices.java
new file mode 100644
index 0000000..498cb85
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/model/Devices.java
@@ -0,0 +1,59 @@
+package com.dharashah.showcaseandroidapp.model;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Created by USER on 21-01-2016.
+ */
+public class Devices {
+ @SerializedName("id")
+ private int deviceId;
+ @SerializedName("androidId")
+ private int androidId;
+ @SerializedName("imageUrl")
+ private String imageURL;
+ @SerializedName("name")
+ private String deviceName;
+ @SerializedName("snippet")
+ private String deviceDesc;
+
+ public int getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(int deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ public int getAndroidId() {
+ return androidId;
+ }
+
+ public void setAndroidId(int androidId) {
+ this.androidId = androidId;
+ }
+
+ public String getImageURL() {
+ return imageURL;
+ }
+
+ public void setImageURL(String imageURL) {
+ this.imageURL = imageURL;
+ }
+
+ public String getDeviceName() {
+ return deviceName;
+ }
+
+ public void setDeviceName(String deviceName) {
+ this.deviceName = deviceName;
+ }
+
+ public String getDeviceDesc() {
+ return deviceDesc;
+ }
+
+ public void setDeviceDesc(String deviceDesc) {
+ this.deviceDesc = deviceDesc;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/network/ApiCalls.java b/app/src/main/java/com/dharashah/showcaseandroidapp/network/ApiCalls.java
new file mode 100644
index 0000000..19648ce
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/network/ApiCalls.java
@@ -0,0 +1,43 @@
+package com.dharashah.showcaseandroidapp.network;
+
+import android.content.Context;
+
+import com.android.volley.RequestQueue;
+import com.android.volley.toolbox.Volley;
+
+/**
+ * Created by Dhara shah on 22/12/2015.
+ * SingleTon class that initializes the queue to
+ * load the images from the network
+ */
+public class ApiCalls {
+ private static ApiCalls mApiCall;
+ private static Context mContext;
+
+ /**
+ * Instantiates ApiCalls instance
+ * @param context
+ * @return
+ */
+ public static ApiCalls getInstance(Context context) {
+ mContext = context;
+ if(mApiCall == null) {
+ mApiCall = new ApiCalls();
+ }
+ return mApiCall;
+ }
+
+ private RequestQueue queue;
+
+ /**
+ * Instantiates the queue
+ * @return
+ */
+ public RequestQueue getRequestQueue() {
+ if(queue == null) {
+ queue = Volley.newRequestQueue(mContext.getApplicationContext());
+ queue.start();
+ }
+ return queue;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/network/RestClient.java b/app/src/main/java/com/dharashah/showcaseandroidapp/network/RestClient.java
new file mode 100644
index 0000000..2fa1348
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/network/RestClient.java
@@ -0,0 +1,85 @@
+package com.dharashah.showcaseandroidapp.network;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkInfo;
+import android.os.Build;
+
+import com.dharashah.showcaseandroidapp.ShowCaseApp;
+import com.dharashah.showcaseandroidapp.network.interfaces.ApiService;
+
+import retrofit.GsonConverterFactory;
+import retrofit.Retrofit;
+
+
+public class RestClient {
+ public static final String BASE_URL = "http://mobilesandboxdev.azurewebsites.net/";
+ private ApiService mApiService;
+
+ /**
+ * Initializes Retrofit and sets the base point of connection
+ */
+ public RestClient() {
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl(BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create())
+ .build();
+ mApiService = retrofit.create(ApiService.class);
+ }
+
+ /**
+ * returns the instance of ApiService needed to make service calls
+ * @return
+ */
+ public ApiService getApiService() {
+ return mApiService;
+ }
+
+ /**
+ * Checks the availability of internet
+ * @return
+ */
+ public static boolean isNetworkAvailable() {
+ boolean haveConnectedWifi = false;
+ boolean haveConnectedMobile = false;
+
+ ConnectivityManager cm =
+ (ConnectivityManager) ShowCaseApp.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ Network[] networks = cm.getAllNetworks();
+ NetworkInfo networkInfo;
+ for (Network network : networks) {
+ networkInfo = cm.getNetworkInfo(network);
+
+ if (networkInfo.getTypeName().equalsIgnoreCase("WIFI"))
+ if (networkInfo.isConnected())
+ haveConnectedWifi = true;
+ if (networkInfo.getTypeName().equalsIgnoreCase("MOBILE"))
+ if (networkInfo.isConnected())
+ haveConnectedMobile = true;
+
+ if (networkInfo.getState().equals(NetworkInfo.State.CONNECTED)) {
+ return true;
+ }
+ }
+ }else {
+ //noinspection deprecation
+ NetworkInfo[] info = cm.getAllNetworkInfo();
+ if (info != null) {
+ for (NetworkInfo anInfo : info) {
+ if (anInfo.getState() == NetworkInfo.State.CONNECTED) {
+ if (anInfo.getTypeName().equalsIgnoreCase("WIFI"))
+ if (anInfo.isConnected())
+ haveConnectedWifi = true;
+ if (anInfo.getTypeName().equalsIgnoreCase("MOBILE"))
+ if (anInfo.isConnected())
+ haveConnectedMobile = true;
+ }
+ }
+ }
+ }
+ return haveConnectedWifi || haveConnectedMobile;
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/network/interfaces/ApiService.java b/app/src/main/java/com/dharashah/showcaseandroidapp/network/interfaces/ApiService.java
new file mode 100644
index 0000000..e2193da
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/network/interfaces/ApiService.java
@@ -0,0 +1,44 @@
+package com.dharashah.showcaseandroidapp.network.interfaces;
+
+import com.dharashah.showcaseandroidapp.model.AllData;
+import com.dharashah.showcaseandroidapp.model.AndroidHistory;
+import com.dharashah.showcaseandroidapp.model.Devices;
+
+import java.util.List;
+
+import retrofit.Call;
+import retrofit.http.Body;
+import retrofit.http.DELETE;
+import retrofit.http.GET;
+import retrofit.http.POST;
+import retrofit.http.Path;
+import retrofit.http.Query;
+
+/**
+ * Created by Dhara Shah on 22/01/2016.
+ * Holds all the webservice calls to be made.
+ */
+public interface ApiService {
+ @GET("android")
+ Call> getAndroidVersions(@Query(value = "_start", encoded = true) int startValue,
+ @Query(value="_end", encoded = true) int endValue);
+
+ @GET("devices?_sort=id&_order=DESC")
+ Call> getDevices(@Query(value = "_start", encoded = true) int startValue,
+ @Query(value="_end", encoded = true) int endValue);
+
+ @GET("db")
+ Call getAllData();
+
+ @POST("android")
+ Call addAndroidVersion(@Body AndroidHistory androidHistory);
+
+ @POST("devices")
+ Call addDevice(@Body Devices device);
+
+ @DELETE("android/{id}")
+ Call deleteVersion(@Path("id") int androidId);
+
+ @DELETE("devices/{id}")
+ Call deleteDevice(@Path("id") int deviceId);
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/prefs/SharedPrefs.java b/app/src/main/java/com/dharashah/showcaseandroidapp/prefs/SharedPrefs.java
new file mode 100644
index 0000000..e4dae79
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/prefs/SharedPrefs.java
@@ -0,0 +1,75 @@
+package com.dharashah.showcaseandroidapp.prefs;
+
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+
+import com.dharashah.showcaseandroidapp.ShowCaseApp;
+
+/**
+ * Sharedpreference class that stores the values in the sharedpreference
+ * related to the app
+ *
+ * @author Dhara Shah
+ */
+public class SharedPrefs {
+ public static final String DEVICE_START_COUNT = "device_start_count";
+ public static final String HISTORY_START_COUNT = "history_start_count";
+ public static final String DEVICE_END_COUNT = "device_end_count";
+ public static final String HISTORY_END_COUNT = "history_end_count";
+
+ private static final String PREFS_NAME = "ShowCaseAndroidApp";
+
+ public static SharedPreferences getPrefs() {
+ return ShowCaseApp.getAppContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ }
+
+ public static String getString(String key, String defaultValue) {
+ SharedPreferences sp = getPrefs();
+ return sp.getString(key, defaultValue);
+ }
+
+ public static int getInt(String key, int defaultValue) {
+ SharedPreferences sp = getPrefs();
+ return sp.getInt(key, defaultValue);
+ }
+
+ public static boolean getBoolean(String key, boolean defaultValue) {
+ SharedPreferences sp = getPrefs();
+ return sp.getBoolean(key, defaultValue);
+ }
+
+ public static void putString(String key, String value) {
+ SharedPreferences sp = getPrefs();
+ Editor editor = sp.edit();
+ editor.putString(key, value);
+ editor.commit();
+ }
+
+ public static void putInt(String key, int value) {
+ SharedPreferences sp = getPrefs();
+ Editor editor = sp.edit();
+ editor.putInt(key, value);
+ editor.commit();
+ }
+
+ public static void putStrings(String[] keys, String[] values) {
+ SharedPreferences sp = getPrefs();
+ Editor editor = sp.edit();
+
+ for (int i = 0; i < keys.length; i++) {
+ String key = keys[i];
+ String value = values[i];
+ editor.putString(key, value);
+ }
+ editor.commit();
+ }
+
+ public static void putBoolean(String key, boolean value) {
+ SharedPreferences sp = getPrefs();
+ Editor editor = sp.edit();
+ editor.putBoolean(key, value);
+ editor.commit();
+ }
+}
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/utility/CustomExceptionHandler.java b/app/src/main/java/com/dharashah/showcaseandroidapp/utility/CustomExceptionHandler.java
new file mode 100644
index 0000000..59d7994
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/utility/CustomExceptionHandler.java
@@ -0,0 +1,172 @@
+package com.dharashah.showcaseandroidapp.utility;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.AsyncTask;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.ProtocolException;
+import java.net.URL;
+import java.net.URLEncoder;
+
+public class CustomExceptionHandler implements UncaughtExceptionHandler {
+
+ private UncaughtExceptionHandler defaultUEH;
+ public static String sendErrorLogsTo = "dhara.shah@credencys.com" ;
+
+ Activity activity;
+
+ public CustomExceptionHandler(Activity activity) {
+ this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
+ this.activity = activity;
+ }
+
+ public void uncaughtException(Thread t, Throwable e) {
+
+ final Writer result = new StringWriter();
+ final PrintWriter printWriter = new PrintWriter(result);
+ e.printStackTrace(printWriter);
+ String stacktrace = result.toString();
+ printWriter.close();
+ String filename = "error" + System.nanoTime() + ".stacktrace";
+
+ sendToServer(stacktrace, filename);
+
+ StackTraceElement[] arr = e.getStackTrace();
+ String report = e.toString() + "\n\n";
+ report += "--------- Stack trace ---------\n\n";
+ for (int i = 0; i < arr.length; i++) {
+ report += " " + arr[i].toString() + "\n";
+ }
+ report += "-------------------------------\n\n";
+
+ report += "--------- Cause ---------\n\n";
+ Throwable cause = e.getCause();
+ if (cause != null) {
+ report += cause.toString() + "\n\n";
+ arr = cause.getStackTrace();
+ for (int i = 0; i < arr.length; i++) {
+ report += " " + arr[i].toString() + "\n";
+ }
+ }
+ report += "-------------------------------\n\n";
+
+ defaultUEH.uncaughtException(t, e);
+ }
+
+ private void sendToServer(String stacktrace, String filename) {
+ AsyncTaskClass async = new AsyncTaskClass(stacktrace, filename,
+ getAppLable(activity));
+ async.execute("");
+ }
+
+ public String getAppLable(Context pContext) {
+ PackageManager lPackageManager = pContext.getPackageManager();
+ ApplicationInfo lApplicationInfo = null;
+ try {
+ lApplicationInfo = lPackageManager.getApplicationInfo(
+ pContext.getApplicationInfo().packageName, 0);
+ } catch (final NameNotFoundException e) {
+ }
+ return (String) (lApplicationInfo != null ? lPackageManager
+ .getApplicationLabel(lApplicationInfo) : "Unknown");
+ }
+
+ public class AsyncTaskClass extends AsyncTask {
+ InputStream is = null;
+ String stacktrace;
+ final String filename;
+ String applicationName;
+
+ AsyncTaskClass(final String stacktrace, final String filename,
+ String applicationName) {
+ this.applicationName = applicationName;
+ this.stacktrace = stacktrace;
+ this.filename = filename;
+ }
+
+ @Override
+ protected InputStream doInBackground(String... params)
+ {
+ HttpURLConnection connection = null;
+ try {
+ String urlMain ="http://suo-yang.com/books/sendErrorLog/sendErrorLogs.php";
+ URL url = new URL("http://suo-yang.com/books/sendErrorLog/sendErrorLogs.php");
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+ connection.connect();
+
+ String strParamsToSend = "data=" + URLEncoder.encode(stacktrace, "UTF-8") +
+ "&to=" + URLEncoder.encode(sendErrorLogsTo, "UTF-8") +
+ "&subject=" + URLEncoder.encode(applicationName, "UTF-8");
+
+ if(strParamsToSend != null) {
+ OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
+ out.write(strParamsToSend);
+ out.flush();
+ out.close();
+ }
+
+ is = connection.getInputStream();
+ getStringFromInputStream(is);
+
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (ProtocolException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ connection.disconnect();
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(InputStream result) {
+ super.onPostExecute(result);
+ }
+ }
+
+ // convert InputStream to String
+ private static String getStringFromInputStream(InputStream is) {
+ BufferedReader reader = null;
+ StringBuffer buffer = new StringBuffer();
+ try {
+ reader = new BufferedReader(new InputStreamReader(is));
+ String line = "";
+ while ((line = reader.readLine()) != null) {
+ buffer.append((line + "\n"));
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ //Mint.logException(e);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ //Mint.logException(e);
+ }
+ }
+ return buffer.toString();
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/dharashah/showcaseandroidapp/utility/CustomInputValidator.java b/app/src/main/java/com/dharashah/showcaseandroidapp/utility/CustomInputValidator.java
new file mode 100644
index 0000000..944d67d
--- /dev/null
+++ b/app/src/main/java/com/dharashah/showcaseandroidapp/utility/CustomInputValidator.java
@@ -0,0 +1,123 @@
+package com.dharashah.showcaseandroidapp.utility;
+
+
+import android.support.v4.content.ContextCompat;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+
+import com.dharashah.showcaseandroidapp.R;
+import com.dharashah.showcaseandroidapp.ShowCaseApp;
+import com.rengwuxian.materialedittext.MaterialEditText;
+
+public class CustomInputValidator implements TextWatcher {
+ private MaterialEditText et;
+
+ /**
+ * @param editText
+ */
+ public CustomInputValidator(MaterialEditText editText) {
+ this.et = editText;
+ }
+
+ /**
+ * Check error function for all the edittext used in application.
+ *
+ * @param editText
+ * @return boolean
+ */
+ public static boolean checkError(MaterialEditText editText) {
+ switch (editText.getId()) {
+ case R.id.etAndroidName:
+ if (TextUtils.isEmpty(editText.getText().toString())) {
+ editText.setUnderlineColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.setHintTextColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.requestFocus();
+ return true;
+ }
+ break;
+ case R.id.etDeviceName:
+ if (TextUtils.isEmpty(editText.getText().toString())) {
+ editText.setUnderlineColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.setHintTextColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.requestFocus();
+ return true;
+ }
+ break;
+ case R.id.etDeviceDescription:
+ if (TextUtils.isEmpty(editText.getText().toString())) {
+ editText.setUnderlineColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.setHintTextColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.requestFocus();
+ return true;
+ }
+ break;
+ case R.id.etAndroidVersion:
+ if (TextUtils.isEmpty(editText.getText().toString())) {
+ editText.setUnderlineColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.setHintTextColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.requestFocus();
+ return true;
+ }
+ break;
+ case R.id.etAndroidCodeName:
+ if (TextUtils.isEmpty(editText.getText().toString())) {
+ editText.setUnderlineColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.setHintTextColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.requestFocus();
+ return true;
+ }
+ break;
+ case R.id.etAndroidTarget:
+ if (TextUtils.isEmpty(editText.getText().toString())) {
+ editText.setUnderlineColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.setHintTextColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.requestFocus();
+ return true;
+ }
+ break;
+ case R.id.etDistribution:
+ if (TextUtils.isEmpty(editText.getText().toString())) {
+ editText.setUnderlineColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.setHintTextColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.error_color));
+ editText.requestFocus();
+ return true;
+ }
+ break;
+ }
+ return false;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see android.text.TextWatcher#beforeTextChanged(java.lang.CharSequence, int, int, int)
+ */
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see android.text.TextWatcher#onTextChanged(java.lang.CharSequence, int, int, int)
+ */
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ if (!checkError(et)) {
+ et.setUnderlineColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.colorPrimary));
+ et.setHintTextColor(ContextCompat.getColor(ShowCaseApp.getAppContext(), R.color.hint_text));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see android.text.TextWatcher#afterTextChanged(android.text.Editable)
+ */
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+
+}
diff --git a/app/src/main/res/anim/slide_in_down.xml b/app/src/main/res/anim/slide_in_down.xml
new file mode 100644
index 0000000..c3bfd2c
--- /dev/null
+++ b/app/src/main/res/anim/slide_in_down.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_in_up.xml b/app/src/main/res/anim/slide_in_up.xml
new file mode 100644
index 0000000..24ef764
--- /dev/null
+++ b/app/src/main/res/anim/slide_in_up.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_out_down.xml b/app/src/main/res/anim/slide_out_down.xml
new file mode 100644
index 0000000..0f33954
--- /dev/null
+++ b/app/src/main/res/anim/slide_out_down.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_out_up.xml b/app/src/main/res/anim/slide_out_up.xml
new file mode 100644
index 0000000..12607af
--- /dev/null
+++ b/app/src/main/res/anim/slide_out_up.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_normal.xml b/app/src/main/res/drawable/button_normal.xml
new file mode 100644
index 0000000..30bbc80
--- /dev/null
+++ b/app/src/main/res/drawable/button_normal.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_pressed.xml b/app/src/main/res/drawable/button_pressed.xml
new file mode 100644
index 0000000..1bc0000
--- /dev/null
+++ b/app/src/main/res/drawable/button_pressed.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/button_selector.xml b/app/src/main/res/drawable/button_selector.xml
new file mode 100644
index 0000000..13dedf5
--- /dev/null
+++ b/app/src/main/res/drawable/button_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/item_selector.xml b/app/src/main/res/drawable/item_selector.xml
new file mode 100644
index 0000000..5dce46d
--- /dev/null
+++ b/app/src/main/res/drawable/item_selector.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/tooltip_box.9.png b/app/src/main/res/drawable/tooltip_box.9.png
new file mode 100644
index 0000000..d7a83ac
Binary files /dev/null and b/app/src/main/res/drawable/tooltip_box.9.png differ
diff --git a/app/src/main/res/drawable/white_corner_box.xml b/app/src/main/res/drawable/white_corner_box.xml
new file mode 100644
index 0000000..015e770
--- /dev/null
+++ b/app/src/main/res/drawable/white_corner_box.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_add_device.xml b/app/src/main/res/layout/activity_add_device.xml
new file mode 100644
index 0000000..b8965f1
--- /dev/null
+++ b/app/src/main/res/layout/activity_add_device.xml
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_add_history.xml b/app/src/main/res/layout/activity_add_history.xml
new file mode 100644
index 0000000..bb6a4f7
--- /dev/null
+++ b/app/src/main/res/layout/activity_add_history.xml
@@ -0,0 +1,254 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..b3184b9
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_devices.xml b/app/src/main/res/layout/fragment_devices.xml
new file mode 100644
index 0000000..5e4680e
--- /dev/null
+++ b/app/src/main/res/layout/fragment_devices.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_history.xml b/app/src/main/res/layout/fragment_history.xml
new file mode 100644
index 0000000..f54d019
--- /dev/null
+++ b/app/src/main/res/layout/fragment_history.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/individual_front_row.xml b/app/src/main/res/layout/individual_front_row.xml
new file mode 100644
index 0000000..7b60ea2
--- /dev/null
+++ b/app/src/main/res/layout/individual_front_row.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/individual_row_android_versions.xml b/app/src/main/res/layout/individual_row_android_versions.xml
new file mode 100644
index 0000000..6407091
--- /dev/null
+++ b/app/src/main/res/layout/individual_row_android_versions.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/individual_swipe_row.xml b/app/src/main/res/layout/individual_swipe_row.xml
new file mode 100644
index 0000000..85f3a73
--- /dev/null
+++ b/app/src/main/res/layout/individual_swipe_row.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/individual_swipe_versions.xml b/app/src/main/res/layout/individual_swipe_versions.xml
new file mode 100644
index 0000000..aefdb59
--- /dev/null
+++ b/app/src/main/res/layout/individual_swipe_versions.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/individual_versions_front_row.xml b/app/src/main/res/layout/individual_versions_front_row.xml
new file mode 100644
index 0000000..1feed3e
--- /dev/null
+++ b/app/src/main/res/layout/individual_versions_front_row.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_toolbar.xml b/app/src/main/res/layout/layout_toolbar.xml
new file mode 100644
index 0000000..075d3b2
--- /dev/null
+++ b/app/src/main/res/layout/layout_toolbar.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/pop_up_android_versions.xml b/app/src/main/res/layout/pop_up_android_versions.xml
new file mode 100644
index 0000000..c31dc3f
--- /dev/null
+++ b/app/src/main/res/layout/pop_up_android_versions.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/pop_up_device_details.xml b/app/src/main/res/layout/pop_up_device_details.xml
new file mode 100644
index 0000000..0912365
--- /dev/null
+++ b/app/src/main/res/layout/pop_up_device_details.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_add_device.xml b/app/src/main/res/menu/menu_add_device.xml
new file mode 100644
index 0000000..deda7a7
--- /dev/null
+++ b/app/src/main/res/menu/menu_add_device.xml
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/arrow.png b/app/src/main/res/mipmap-hdpi/arrow.png
new file mode 100644
index 0000000..c96a062
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/arrow.png differ
diff --git a/app/src/main/res/mipmap-hdpi/delete.png b/app/src/main/res/mipmap-hdpi/delete.png
new file mode 100644
index 0000000..e147cba
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/delete.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_action_accept.png b/app/src/main/res/mipmap-hdpi/ic_action_accept.png
new file mode 100644
index 0000000..700fc81
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_action_accept.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/arrow.png b/app/src/main/res/mipmap-mdpi/arrow.png
new file mode 100644
index 0000000..c96a062
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/arrow.png differ
diff --git a/app/src/main/res/mipmap-mdpi/delete.png b/app/src/main/res/mipmap-mdpi/delete.png
new file mode 100644
index 0000000..a385658
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/delete.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_action_accept.png b/app/src/main/res/mipmap-mdpi/ic_action_accept.png
new file mode 100644
index 0000000..41107b8
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_action_accept.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/arrow.png b/app/src/main/res/mipmap-xhdpi/arrow.png
new file mode 100644
index 0000000..5ae0f36
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/arrow.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/delete.png b/app/src/main/res/mipmap-xhdpi/delete.png
new file mode 100644
index 0000000..c986bae
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/delete.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_action_accept.png b/app/src/main/res/mipmap-xhdpi/ic_action_accept.png
new file mode 100644
index 0000000..6ee32b6
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_action_accept.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/arrow.png b/app/src/main/res/mipmap-xxhdpi/arrow.png
new file mode 100644
index 0000000..8e6802a
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/arrow.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/delete.png b/app/src/main/res/mipmap-xxhdpi/delete.png
new file mode 100644
index 0000000..030c20e
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/delete.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_action_accept.png b/app/src/main/res/mipmap-xxhdpi/ic_action_accept.png
new file mode 100644
index 0000000..68c41de
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_action_accept.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..7fa6831
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #626262
+ #efefec
+ #FF414040
+ #FF565656
+ #FF037C89
+ #FF03717C
+ #FF890325
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..47c8224
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..c584b40
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ ShowCaseAndroidApp
+ Please check your internet connection
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..8c3fc0a
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..9405f3f
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.2.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..05ef575
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..f23df6e
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Oct 21 11:34:03 PDT 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/showcaseandroidapp2.iml b/showcaseandroidapp2.iml
new file mode 100644
index 0000000..45427a4
--- /dev/null
+++ b/showcaseandroidapp2.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file