diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..8fc1ee5
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+TheGimbalStore
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..fe865d3
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..59436c9
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..aeb1ebd
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..c80f219
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/TheGimbalStore.iml b/TheGimbalStore.iml
new file mode 100644
index 0000000..0bb6048
--- /dev/null
+++ b/TheGimbalStore.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/app.iml b/app/app.iml
new file mode 100644
index 0000000..c3a7062
--- /dev/null
+++ b/app/app.iml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..38ecb3e
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "com.avnet.gears.codes.gimbal.store"
+ minSdkVersion 21
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile files('libs/gson-2.3.1.jar')
+ compile 'com.android.support:support-v4:21.0.3'
+ compile 'com.android.support:support-v13:21.0.3'
+}
diff --git a/app/libs/gson-2.3.1.jar b/app/libs/gson-2.3.1.jar
new file mode 100644
index 0000000..250132c
Binary files /dev/null and b/app/libs/gson-2.3.1.jar differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..c46101d
--- /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 /Users/914889/Library/Android/sdk/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/avnet/gears/codes/gimbal/store/ApplicationTest.java b/app/src/androidTest/java/com/avnet/gears/codes/gimbal/store/ApplicationTest.java
new file mode 100644
index 0000000..008906f
--- /dev/null
+++ b/app/src/androidTest/java/com/avnet/gears/codes/gimbal/store/ApplicationTest.java
@@ -0,0 +1,13 @@
+package com.avnet.gears.codes.gimbal.store;
+
+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..295c5d7
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/activity/FeedListActivity.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/activity/FeedListActivity.java
new file mode 100644
index 0000000..65d9315
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/activity/FeedListActivity.java
@@ -0,0 +1,195 @@
+package com.avnet.gears.codes.gimbal.store.activity;
+
+import java.util.Locale;
+
+import android.app.Activity;
+import android.app.ActionBar;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.support.v13.app.FragmentPagerAdapter;
+import android.os.Bundle;
+import android.support.v4.view.ViewPager;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.avnet.gears.codes.gimbal.store.R;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.INTENT_EXTRA_ATTR_KEY;
+
+public class FeedListActivity extends Activity implements ActionBar.TabListener {
+
+ /**
+ * The {@link android.support.v4.view.PagerAdapter} that will provide
+ * fragments for each of the sections. We use a
+ * {@link FragmentPagerAdapter} derivative, which will keep every
+ * loaded fragment in memory. If this becomes too memory intensive, it
+ * may be best to switch to a
+ * {@link android.support.v13.app.FragmentStatePagerAdapter}.
+ */
+ SectionsPagerAdapter mSectionsPagerAdapter;
+
+ /**
+ * The {@link ViewPager} that will host the section contents.
+ */
+ ViewPager mViewPager;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_feed_list);
+
+ Bundle bundle = getIntent().getExtras();
+ Log.d("DEBUG NOTIFY", "getting data from the notification "
+ + bundle.getString(INTENT_EXTRA_ATTR_KEY.SELECTED_NOTIFICATION_ID.toString()));
+
+ // Set up the action bar.
+ final ActionBar actionBar = getActionBar();
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+
+ // Create the adapter that will return a fragment for each of the three
+ // primary sections of the activity.
+ mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
+
+ // Set up the ViewPager with the sections adapter.
+ mViewPager = (ViewPager) findViewById(R.id.pager);
+ mViewPager.setAdapter(mSectionsPagerAdapter);
+
+ // When swiping between different sections, select the corresponding
+ // tab. We can also use ActionBar.Tab#select() to do this if we have
+ // a reference to the Tab.
+ mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
+ @Override
+ public void onPageSelected(int position) {
+ actionBar.setSelectedNavigationItem(position);
+ }
+ });
+
+ // For each of the sections in the app, add a tab to the action bar.
+ for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
+ // Create a tab with text corresponding to the page title defined by
+ // the adapter. Also specify this Activity object, which implements
+ // the TabListener interface, as the callback (listener) for when
+ // this tab is selected.
+ actionBar.addTab(
+ actionBar.newTab()
+ .setText(mSectionsPagerAdapter.getPageTitle(i))
+ .setTabListener(this));
+ }
+ }
+
+
+ @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_feed_list, 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_settings) {
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ // When the given tab is selected, switch to the corresponding page in
+ // the ViewPager.
+ mViewPager.setCurrentItem(tab.getPosition());
+ }
+
+ @Override
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ }
+
+ @Override
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ }
+
+ /**
+ * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
+ * one of the sections/tabs/pages.
+ */
+ public class SectionsPagerAdapter extends FragmentPagerAdapter {
+
+ public SectionsPagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ // getItem is called to instantiate the fragment for the given page.
+ // Return a PlaceholderFragment (defined as a static inner class below).
+ return PlaceholderFragment.newInstance(position + 1);
+ }
+
+ @Override
+ public int getCount() {
+ // Show 3 total pages.
+ return 3;
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ Locale l = Locale.getDefault();
+ switch (position) {
+ case 0:
+ return getString(R.string.title_section1).toUpperCase(l);
+ case 1:
+ return getString(R.string.title_section2).toUpperCase(l);
+ case 2:
+ return getString(R.string.title_section3).toUpperCase(l);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * A placeholder fragment containing a simple view.
+ */
+ public static class PlaceholderFragment extends Fragment {
+ /**
+ * The fragment argument representing the section number for this
+ * fragment.
+ */
+ private static final String ARG_SECTION_NUMBER = "section_number";
+
+ /**
+ * Returns a new instance of this fragment for the given section
+ * number.
+ */
+ public static PlaceholderFragment newInstance(int sectionNumber) {
+ PlaceholderFragment fragment = new PlaceholderFragment();
+ Bundle args = new Bundle();
+ args.putInt(ARG_SECTION_NUMBER, sectionNumber);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ public PlaceholderFragment() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.fragment_feed_list, container, false);
+ return rootView;
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/activity/HomeActivity.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/activity/HomeActivity.java
new file mode 100644
index 0000000..34e196c
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/activity/HomeActivity.java
@@ -0,0 +1,229 @@
+package com.avnet.gears.codes.gimbal.store.activity;
+
+import android.app.Activity;
+
+import android.app.ActionBar;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.ProgressDialog;
+import android.os.Bundle;
+import android.support.v4.widget.DrawerLayout;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.avnet.gears.codes.gimbal.store.adapter.CategoryViewAdapter;
+import com.avnet.gears.codes.gimbal.store.async.response.processor.impl.CategoryListProcessor;
+import com.avnet.gears.codes.gimbal.store.bean.CategoryBean;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.StoreParameterKeys;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.HTTP_METHODS;
+import com.avnet.gears.codes.gimbal.store.fragment.NavigationDrawerFragment;
+import com.avnet.gears.codes.gimbal.store.R;
+import com.avnet.gears.codes.gimbal.store.handler.HttpConnectionAsyncTask;
+import com.avnet.gears.codes.gimbal.store.handler.ImageResponseAsyncTask;
+import com.avnet.gears.codes.gimbal.store.utils.ServerURLUtil;
+import com.avnet.gears.codes.gimbal.store.utils.TypeConversionUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+
+public class HomeActivity extends Activity
+ implements NavigationDrawerFragment.NavigationDrawerCallbacks {
+
+ /**
+ * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
+ */
+ private NavigationDrawerFragment mNavigationDrawerFragment;
+
+ // list of categories to be shown on drawer fragment
+ protected List mCategoryList;
+ // section label
+ private TextView sectionLabelView ;
+ /**
+ * Used to store the last screen title. For use in {@link #restoreActionBar()}.
+ */
+ private CharSequence mTitle;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_home);
+ // fetch the category list
+ mCategoryList = new ArrayList();
+ // instantiate spinner
+ ProgressDialog progress = new ProgressDialog(this);
+ progress.setTitle("Loading");
+ progress.setMessage("Wait while loading...");
+ progress.show();
+ mNavigationDrawerFragment = (NavigationDrawerFragment)
+ getFragmentManager().findFragmentById(R.id.navigation_drawer);
+ // initialize bean to process value from async net call for category
+ CategoryListProcessor cListProcessor = new CategoryListProcessor(this,
+ mNavigationDrawerFragment,
+ (DrawerLayout)findViewById(R.id.drawer_layout),
+ mCategoryList, progress);
+
+ mNavigationDrawerFragment.setUp(
+ R.id.navigation_drawer,
+ (DrawerLayout)findViewById(R.id.drawer_layout),
+ TypeConversionUtil.getCategoryTitleList(mCategoryList));
+
+ /*
+ Log.d("DEBUG NOTIFY", "Sending notification from Home Activity");
+ Intent targetIntent = new Intent(getApplicationContext(), FeedListActivity.class);
+ targetIntent.putExtra(INTENT_EXTRA_ATTR_KEY.SELECTED_NOTIFICATION_ID.toString(), "notify_id_111");
+ NotificationUtil.notify(this, targetIntent, "Home Notification", " Notification test from home activity",
+ R.drawable.ic_drawer,true, null);
+ Log.d("DEBUG NOTIFY", "End of notification sending from Home Activity");
+ */
+
+ mTitle = getTitle();
+
+
+ // Log.d("DEBUG", "Server URL = " + ServerURLUtil.getStoreServletServerURL(getResources()));
+ Map paramsMap = ServerURLUtil.getBasicConfigParamsMap(getResources());
+ paramsMap.put(StoreParameterKeys.catalogId.toString(), "10001");
+ paramsMap.put(StoreParameterKeys.identifier.toString(), "top");
+ paramsMap.put(StoreParameterKeys.type.toString(), "category");
+ // Log.d("DEBUG", paramsMap.toString());
+
+ HttpConnectionAsyncTask handler = new HttpConnectionAsyncTask(HTTP_METHODS.GET,
+ ServerURLUtil.getStoreServletServerURL(getResources()),
+ paramsMap,
+ cListProcessor);
+ handler.execute(new String[] {});
+ }
+
+ @Override
+ public void onNavigationDrawerItemSelected(int position) {
+ // update the main content by replacing fragments
+ FragmentManager fragmentManager = getFragmentManager();
+ fragmentManager.beginTransaction()
+ .replace(R.id.container, PlaceholderFragment.newInstance(position, mCategoryList))
+ .commit();
+ }
+
+ public void onSectionAttached(int number) {
+ if(mCategoryList != null && !mCategoryList.isEmpty()) {
+ mTitle = mCategoryList.get(number).getName();
+ } else {
+ mTitle = "Home";
+ }
+ }
+
+ public void restoreActionBar() {
+ ActionBar actionBar = getActionBar();
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setTitle(mTitle);
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ if (!mNavigationDrawerFragment.isDrawerOpen()) {
+ // Only show items in the action bar relevant to this screen
+ // if the drawer is not showing. Otherwise, let the drawer
+ // decide what to show in the action bar.
+ getMenuInflater().inflate(R.menu.menu_home, menu);
+ restoreActionBar();
+ return true;
+ }
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @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_settings) {
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * A placeholder fragment containing a simple view.
+ */
+ public static class PlaceholderFragment extends Fragment {
+ /**
+ * The fragment argument representing the section number for this
+ * fragment.
+ */
+ private static final String ARG_SECTION_NUMBER = "section_number";
+ private TextView sectionLabelTextView ;
+ private ImageView imageView;
+ private ListView allListItemsView;
+ private CategoryBean selectedCategoryBean;
+ private static List mCategoryBeanList;
+ /**
+ * Returns a new instance of this fragment for the given section
+ * number.
+ */
+ public static PlaceholderFragment newInstance(int sectionNumber, List categoryBeanList) {
+ PlaceholderFragment fragment = new PlaceholderFragment();
+ Bundle args = new Bundle();
+ mCategoryBeanList = categoryBeanList;
+ // Log.d("DEBUG", "" + categoryBeanList);
+ args.putInt(ARG_SECTION_NUMBER, sectionNumber);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ public PlaceholderFragment() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Log.d("DEBUG", "in PlaceHolderFragment.onCreateView()");
+ View rootView = inflater.inflate(R.layout.fragment_home, container, false);
+ sectionLabelTextView = (TextView)rootView.findViewById(R.id.section_label);
+ allListItemsView = (ListView) rootView.findViewById(R.id.subcategories_list_view);
+ // use the category Id obtained from HomeActivity to fetch and view list of subcategory items
+ imageView = (ImageView) rootView.findViewById(R.id.image_view);
+ if(selectedCategoryBean != null) {
+ if(selectedCategoryBean.getThumbnail() != null) {
+ ImageResponseAsyncTask imageTask = new ImageResponseAsyncTask(ServerURLUtil.getAbsoluteUrlFor(getResources(), selectedCategoryBean.getThumbnail()), imageView, null);
+ imageTask.execute(new String[]{});
+ }
+ sectionLabelTextView.setText("Showing List of Items of " + selectedCategoryBean.getName());
+ }
+ String[] subCategoryItemsList = new String[] {"subcat1","subcat2","subcat3","subcat4","subcat5","subcat6","subcat7"};
+ CategoryViewAdapter productListAdapter = new CategoryViewAdapter(getActivity(), subCategoryItemsList);
+ allListItemsView.setAdapter(productListAdapter);
+ allListItemsView.refreshDrawableState();
+ return rootView;
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ // Log.d("DEBUG", "in PlaceHolderFragment.onAttach()");
+ HomeActivity callingHomeActivity = (HomeActivity) activity;
+ int selectedPosition = getArguments().getInt(ARG_SECTION_NUMBER);
+ callingHomeActivity.onSectionAttached(
+ selectedPosition);
+ // fetch the selected category id from HomeActivity
+
+ if( mCategoryBeanList != null && !mCategoryBeanList.isEmpty())
+ selectedCategoryBean = mCategoryBeanList.get(selectedPosition);
+
+ // Log.d("DEBUG", "Holder selectedCategoryId=" + selectedCategoryId);
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/adapter/CategoryViewAdapter.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/adapter/CategoryViewAdapter.java
new file mode 100644
index 0000000..1a178d4
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/adapter/CategoryViewAdapter.java
@@ -0,0 +1,43 @@
+package com.avnet.gears.codes.gimbal.store.adapter;
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.avnet.gears.codes.gimbal.store.R;
+
+/**
+ * Created by 914889 on 2/23/15.
+ */
+public class CategoryViewAdapter extends ArrayAdapter {
+ private final Activity context;
+
+ private String[] labelList;
+
+ public CategoryViewAdapter(Activity context,
+ String[] list) {
+ super(context, R.layout.view_subcategory_list_item, list);
+ labelList = list;
+ this.context = context;
+ }
+ @Override
+ public View getView(int position, View view, ViewGroup parent) {
+ LayoutInflater inflater = context.getLayoutInflater();
+ View rowView= inflater.inflate(R.layout.view_subcategory_list_item, null, true);
+ TextView txtTitle = (TextView) rowView.findViewById(R.id.textView1);
+ ImageView[] imageViews = new ImageView[]{
+ (ImageView) rowView.findViewById(R.id.imageButton1),
+ (ImageView) rowView.findViewById(R.id.imageButton2),
+ (ImageView) rowView.findViewById(R.id.imageButton3),
+ (ImageView) rowView.findViewById(R.id.imageButton4)
+ };
+ txtTitle.setText(labelList[position]);
+ for(ImageView imageView : imageViews) {
+ imageView.setImageResource(R.drawable.ic_launcher);
+ }
+ return rowView;
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/AsyncResponseProcessor.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/AsyncResponseProcessor.java
new file mode 100644
index 0000000..4805ea0
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/AsyncResponseProcessor.java
@@ -0,0 +1,14 @@
+package com.avnet.gears.codes.gimbal.store.async.response.processor;
+
+import android.graphics.Bitmap;
+
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants;
+
+/**
+ * Created by 914889 on 2/25/15.
+ */
+public interface AsyncResponseProcessor {
+
+ public boolean doProcess(GimbalStoreConstants.HTTP_RESPONSE_CODES responseCode, String responseString);
+
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/impl/CategoryListProcessor.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/impl/CategoryListProcessor.java
new file mode 100644
index 0000000..1aaae27
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/impl/CategoryListProcessor.java
@@ -0,0 +1,71 @@
+package com.avnet.gears.codes.gimbal.store.async.response.processor.impl;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.support.v4.widget.DrawerLayout;
+import android.util.Log;
+
+import com.avnet.gears.codes.gimbal.store.R;
+import com.avnet.gears.codes.gimbal.store.async.response.processor.AsyncResponseProcessor;
+import com.avnet.gears.codes.gimbal.store.bean.CategoryBean;
+import com.avnet.gears.codes.gimbal.store.bean.CategoryResponseBean;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.HTTP_RESPONSE_CODES;
+import com.avnet.gears.codes.gimbal.store.fragment.NavigationDrawerFragment;
+import com.avnet.gears.codes.gimbal.store.utils.TypeConversionUtil;
+import com.google.gson.Gson;
+import com.google.gson.stream.JsonReader;
+
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by 914889 on 2/25/15.
+ */
+public class CategoryListProcessor implements AsyncResponseProcessor {
+
+ private Activity parentActivity;
+ private NavigationDrawerFragment navigationDrawerFragment;
+ private List categoryBeanList;
+ private DrawerLayout drawerLayout;
+ private ProgressDialog progressDialog;
+
+ public CategoryListProcessor(Activity parentActivity, NavigationDrawerFragment navigationDrawerFragment,
+ DrawerLayout drawerLayout,
+ List categoryBeanList, ProgressDialog progressDialog) {
+ // add parameters and initialize proper values for
+ // sending back the response to the calling activity
+ this.categoryBeanList = categoryBeanList;
+ this.drawerLayout = drawerLayout;
+ this.parentActivity = parentActivity;
+ this.navigationDrawerFragment = navigationDrawerFragment;
+ this.progressDialog = progressDialog;
+
+ }
+ @Override
+ public boolean doProcess(HTTP_RESPONSE_CODES responseCode, String responseString){
+ // Log.d("PROCESS DEBUG", "" + responseCode);
+ responseString = responseString.trim()
+ .replace(GimbalStoreConstants.START_COMMENT_STRING, "")
+ .replace(GimbalStoreConstants.END_COMMENT_STRING, "");
+ if(responseCode == HTTP_RESPONSE_CODES.OK ||
+ responseCode == HTTP_RESPONSE_CODES.CREATED ||
+ responseCode == HTTP_RESPONSE_CODES.ACCEPTED) {
+ Gson gson = new Gson();
+
+ JsonReader reader = new JsonReader(new StringReader(responseString));
+ reader.setLenient(true);
+ CategoryResponseBean responseBean = gson.fromJson(reader, CategoryResponseBean.class);
+ // Log.d("HTTP DEBUG", " Response Bean = " + responseBean);
+ // Set up the drawer.
+ categoryBeanList.addAll(Arrays.asList(responseBean.getCatalogGroupView()));
+ navigationDrawerFragment.setmCategoryTitles(TypeConversionUtil.getCategoryTitleList(categoryBeanList));
+ navigationDrawerFragment.refreshDrawerListView();
+ // hide progress bar
+ progressDialog.dismiss();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/impl/SubcategoryListProcessor.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/impl/SubcategoryListProcessor.java
new file mode 100644
index 0000000..16c7f41
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/async/response/processor/impl/SubcategoryListProcessor.java
@@ -0,0 +1,32 @@
+package com.avnet.gears.codes.gimbal.store.async.response.processor.impl;
+
+import android.widget.ImageView;
+
+import com.avnet.gears.codes.gimbal.store.async.response.processor.AsyncResponseProcessor;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants;
+
+/**
+ * Created by 914889 on 3/4/15.
+ */
+public class SubcategoryListProcessor implements AsyncResponseProcessor {
+
+ private ImageView imageView;
+
+ public SubcategoryListProcessor(ImageView imageView) {
+ this.imageView = imageView;
+ }
+
+ @Override
+ public boolean doProcess(GimbalStoreConstants.HTTP_RESPONSE_CODES responseCode, String responseString) {
+ responseString = responseString.trim()
+ .replace(GimbalStoreConstants.START_COMMENT_STRING, "")
+ .replace(GimbalStoreConstants.END_COMMENT_STRING, "");
+ if(responseCode == GimbalStoreConstants.HTTP_RESPONSE_CODES.OK ||
+ responseCode == GimbalStoreConstants.HTTP_RESPONSE_CODES.CREATED ||
+ responseCode == GimbalStoreConstants.HTTP_RESPONSE_CODES.ACCEPTED) {
+
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/CategoryBean.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/CategoryBean.java
new file mode 100644
index 0000000..f6db4ba
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/CategoryBean.java
@@ -0,0 +1,63 @@
+package com.avnet.gears.codes.gimbal.store.bean;
+
+/**
+ * Created by 914889 on 2/23/15.
+ */
+public class CategoryBean {
+ private String shortdescription;
+ private String identifier;
+ private String name;
+ private String thumbnail;
+ private String uniqueId;
+
+ public String getShortdescription() {
+ return shortdescription;
+ }
+
+ public void setShortdescription(String shortdescription) {
+ this.shortdescription = shortdescription;
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getThumbnail() {
+ return thumbnail;
+ }
+
+ public void setThumbnail(String thumbnail) {
+ this.thumbnail = thumbnail;
+ }
+
+ public String getUniqueId() {
+ return uniqueId;
+ }
+
+ public void setUniqueId(String uniqueId) {
+ this.uniqueId = uniqueId;
+ }
+
+ @Override
+ public String toString() {
+ return "CategoryBean{" +
+ "shortdescription='" + shortdescription + '\'' +
+ ", identifier='" + identifier + '\'' +
+ ", name='" + name + '\'' +
+ ", thumbnail='" + thumbnail + '\'' +
+ ", uniqueId='" + uniqueId + '\'' +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/CategoryResponseBean.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/CategoryResponseBean.java
new file mode 100644
index 0000000..6ff00ad
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/CategoryResponseBean.java
@@ -0,0 +1,65 @@
+package com.avnet.gears.codes.gimbal.store.bean;
+
+import java.util.Arrays;
+
+/**
+ * Created by 914889 on 3/4/15.
+ */
+public class CategoryResponseBean {
+ private String[] storeId;
+ private String[] type;
+ private String[] identifier;
+ private String[] langId;
+ private CategoryBean[] CatalogGroupView;
+
+ public String[] getStoreId() {
+ return storeId;
+ }
+
+ public void setStoreId(String[] storeId) {
+ this.storeId = storeId;
+ }
+
+ public String[] getType() {
+ return type;
+ }
+
+ public void setType(String[] type) {
+ this.type = type;
+ }
+
+ public String[] getIdentifier() {
+ return identifier;
+ }
+
+ public void setIdentifier(String[] identifier) {
+ this.identifier = identifier;
+ }
+
+ public String[] getLangId() {
+ return langId;
+ }
+
+ public void setLangId(String[] langId) {
+ this.langId = langId;
+ }
+
+ public CategoryBean[] getCatalogGroupView() {
+ return CatalogGroupView;
+ }
+
+ public void setCatalogGroupView(CategoryBean[] catalogGroupView) {
+ CatalogGroupView = catalogGroupView;
+ }
+
+ @Override
+ public String toString() {
+ return "CategoryResponseBean{" +
+ "storeId=" + Arrays.toString(storeId) +
+ ", type=" + Arrays.toString(type) +
+ ", identifier=" + Arrays.toString(identifier) +
+ ", langId=" + Arrays.toString(langId) +
+ ", CatalogGroupView=" + Arrays.toString(CatalogGroupView) +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/NotificationActionBean.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/NotificationActionBean.java
new file mode 100644
index 0000000..ce93e52
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/bean/NotificationActionBean.java
@@ -0,0 +1,45 @@
+package com.avnet.gears.codes.gimbal.store.bean;
+
+import android.app.PendingIntent;
+
+/**
+ * Created by 914889 on 2/27/15.
+ */
+public class NotificationActionBean {
+ private int drawableIcon;
+ private String actionTitle;
+ private PendingIntent targetActionPendingIntent;
+
+ public int getDrawableIcon() {
+ return drawableIcon;
+ }
+
+ public void setDrawableIcon(int drawableIcon) {
+ this.drawableIcon = drawableIcon;
+ }
+
+ public String getActionTitle() {
+ return actionTitle;
+ }
+
+ public void setActionTitle(String actionTitle) {
+ this.actionTitle = actionTitle;
+ }
+
+ public PendingIntent getTargetActionPendingIntent() {
+ return targetActionPendingIntent;
+ }
+
+ public void setTargetActionPendingIntent(PendingIntent targetActionPendingIntent) {
+ this.targetActionPendingIntent = targetActionPendingIntent;
+ }
+
+ @Override
+ public String toString() {
+ return "NotificationActionBean{" +
+ "drawableIcon=" + drawableIcon +
+ ", actionTitle='" + actionTitle + '\'' +
+ ", targetActionPendingIntent=" + targetActionPendingIntent +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/client/HttpClient.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/client/HttpClient.java
new file mode 100644
index 0000000..ab181a8
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/client/HttpClient.java
@@ -0,0 +1,198 @@
+package com.avnet.gears.codes.gimbal.store.client;
+
+/**
+ * Created by 914889 on 2/24/15.
+ */
+
+import android.util.Log;
+
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.HTTP_HEADER_VALUES;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.HTTP_REQUEST_HEADER_PROPERTIES;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.HTTP_METHODS;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.Map;
+import java.util.Set;
+
+public class HttpClient {
+
+ private static final int BYTE_ARRAY_LIMIT_1K = 1024;
+
+
+
+ private static final String DELIMITER = "--";
+ private static final String BOUNDARY = "SwA"
+ + Long.toString(System.currentTimeMillis())
+ +"SwA";
+ private static final String HEADER_DELIMITER_VALUE = "\r\n";
+ private static final String DELIMITER_COLAN = ":";
+ private static final String DELIMITER_QUESTION = "?";
+ private static final String DELIMITER_SEMICOLAN = ";";
+ private static final String DELIMITER_AMPERSAND = "&";
+ private static final String DELIMITER_EQUAL = "=";
+
+ private static int MAX_READ_TIMEOUT = 100000;
+ protected HttpClient() {
+ // treating it as a static class
+ }
+ private static HttpURLConnection getPlainHttConnection(String url, HTTP_METHODS httpMethod, boolean doInput,
+ boolean doOutput, boolean isMultiPart, boolean setKeepAlive,
+ boolean useCaches,boolean allowUserInteraction, int timeout) throws MalformedURLException, IOException {
+ HttpURLConnection con = (HttpURLConnection) ( new URL(url)).openConnection();
+ con.setRequestMethod(httpMethod.toString());
+ con.setDoInput(doInput);
+ con.setDoOutput(doOutput);
+ if(httpMethod == HTTP_METHODS.GET) {
+ con.setRequestProperty(HTTP_REQUEST_HEADER_PROPERTIES.CONTENT_LENGTH.getValue(), "0");
+ con.setUseCaches(useCaches);
+ con.setAllowUserInteraction(allowUserInteraction);
+ con.setConnectTimeout(timeout);
+ con.setReadTimeout(timeout);
+ }
+ if( setKeepAlive ) {
+ con.setRequestProperty(HTTP_REQUEST_HEADER_PROPERTIES.CONNECTION.getValue(),
+ HTTP_HEADER_VALUES.CONNECTION_KEEP_ALIVE.getValue());
+ }
+ if( isMultiPart ) {
+ con.setRequestProperty(HTTP_REQUEST_HEADER_PROPERTIES.CONTENT_TYPE.getValue(),
+ MessageFormat.format(HTTP_HEADER_VALUES.CONTENT_TYPE_MULTIPART.getValue(),
+ BOUNDARY)
+ );
+ }
+ con.connect();
+ return con;
+ }
+ public static HttpURLConnection getHttPOSTConnection(String url) throws MalformedURLException, IOException {
+ return getPlainHttConnection(url, HTTP_METHODS.POST, true,
+ true, false, false,
+ false,false,MAX_READ_TIMEOUT);
+ }
+ public static HttpURLConnection getHttpGetConnection(String url, Map paramsMap) throws MalformedURLException, IOException {
+ url += DELIMITER_QUESTION + getStringParameters(paramsMap);
+ return getPlainHttConnection(url, HTTP_METHODS.GET, true,
+ true, false, false,
+ true, true, MAX_READ_TIMEOUT);
+ }
+
+ public static HttpURLConnection getMultiPartHttpPOSTConnection(String url) throws MalformedURLException, IOException {
+ return getPlainHttConnection(url, HTTP_METHODS.POST, true,
+ true, true, true,
+ false,false,MAX_READ_TIMEOUT);
+ }
+
+ private static String getStringParameters(Map parametersMap) {
+ Set keySet = parametersMap.keySet();
+ String outputParametersString = "";
+ for(String key : keySet) {
+ if(!outputParametersString.isEmpty()) {
+ outputParametersString += DELIMITER_AMPERSAND;
+ }
+ outputParametersString += key + DELIMITER_EQUAL + parametersMap.get(key);
+ }
+ return outputParametersString;
+ }
+
+ public static void writePlainParameters(OutputStream outputStream, Map parametersMap) throws IOException {
+ String outputParametersString = getStringParameters(parametersMap);
+ Log.d("HTTP DEBUG", outputParametersString);
+ outputStream.write(outputParametersString.getBytes());
+ }
+ public static byte[] downloadBytesData(HttpURLConnection con) throws IOException{
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ InputStream is = con.getInputStream();
+ byte[] b = new byte[BYTE_ARRAY_LIMIT_1K];
+
+ while ( is.read(b) != -1)
+ byteArrayOutputStream.write(b);
+
+ con.disconnect();
+
+ return byteArrayOutputStream.toByteArray();
+ }
+
+ public static void writeMultiPartFileData(OutputStream os, String paramName, String fileName, byte[] data) throws Exception {
+ os.write( (DELIMITER + BOUNDARY + "\r\n").getBytes());
+ os.write( (HTTP_REQUEST_HEADER_PROPERTIES.CONTENT_DISPOSITION.getValue()
+ + DELIMITER_COLAN + " "
+ + MessageFormat.format(HTTP_HEADER_VALUES.CONTENT_DISPOSITION_FORM_DATA.getValue(),
+ paramName)
+ + DELIMITER_SEMICOLAN
+ + MessageFormat.format(HTTP_HEADER_VALUES.CONTENT_DISPOSITION_FILE_NAME.getValue(),
+ fileName)
+ + HEADER_DELIMITER_VALUE).getBytes());
+ os.write( (HTTP_REQUEST_HEADER_PROPERTIES.CONTENT_TYPE.getValue()
+ + DELIMITER_COLAN + " "
+ + HTTP_HEADER_VALUES.CONTENT_TYPE_OCTET.getValue()
+ + HEADER_DELIMITER_VALUE ).getBytes());
+ os.write( (HTTP_REQUEST_HEADER_PROPERTIES.CONTENT_TRANSFER_ENCODING.getValue()
+ + DELIMITER_COLAN + " "
+ + HTTP_HEADER_VALUES.CONTENT_TRANSFER_ENCODING_BINARY.getValue()
+ + HEADER_DELIMITER_VALUE ).getBytes());
+ os.write("\r\n".getBytes());
+
+ os.write(data);
+
+ os.write(HEADER_DELIMITER_VALUE.getBytes());
+ }
+
+ public static void finishMultipart(OutputStream os) throws Exception {
+ os.write( (DELIMITER + BOUNDARY + DELIMITER + HEADER_DELIMITER_VALUE).getBytes());
+ }
+
+
+ public static String getResponseString(HttpURLConnection con) throws Exception {
+ int responseCode = con.getResponseCode();
+
+ StringBuffer buffer = new StringBuffer();
+ if(GimbalStoreConstants.HTTP_RESPONSE_CODES.getCode(responseCode) == GimbalStoreConstants.HTTP_RESPONSE_CODES.OK
+ || GimbalStoreConstants.HTTP_RESPONSE_CODES.getCode(responseCode) == GimbalStoreConstants.HTTP_RESPONSE_CODES.ACCEPTED) {
+ InputStream is = con.getInputStream();
+ int len = 0;
+
+
+ byte[] data1 = new byte[BYTE_ARRAY_LIMIT_1K];
+ while ( -1 != (len = is.read(data1)) )
+ buffer.append(new String(data1, 0, len));
+
+ }
+ con.disconnect();
+
+ return buffer.toString();
+ }
+
+
+
+ private static void writeMultiPartParamData(OutputStream os, Map parametersMap) throws Exception {
+ Set keySet = parametersMap.keySet();
+
+ for(String key : keySet) {
+ os.write( (DELIMITER + BOUNDARY + HEADER_DELIMITER_VALUE).getBytes());
+ os.write((HTTP_REQUEST_HEADER_PROPERTIES.CONTENT_TYPE.getValue()
+ + DELIMITER_COLAN + " "
+ + HTTP_HEADER_VALUES.CONTENT_TYPE_TEXT.getValue()
+ + HEADER_DELIMITER_VALUE).getBytes());
+
+
+ os.write( (HTTP_REQUEST_HEADER_PROPERTIES.CONTENT_DISPOSITION.getValue()
+ + DELIMITER_COLAN + " "
+ + MessageFormat.format(HTTP_HEADER_VALUES.CONTENT_DISPOSITION_FORM_DATA.getValue(),
+ key)
+ + HEADER_DELIMITER_VALUE).getBytes());
+ os.write( (HEADER_DELIMITER_VALUE
+ + parametersMap.get(key)
+ + HEADER_DELIMITER_VALUE).getBytes());
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/constant/GimbalStoreConstants.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/constant/GimbalStoreConstants.java
new file mode 100644
index 0000000..fcc1781
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/constant/GimbalStoreConstants.java
@@ -0,0 +1,97 @@
+package com.avnet.gears.codes.gimbal.store.constant;
+
+import java.util.List;
+
+/**
+ * Created by 914889 on 2/25/15.
+ */
+public class GimbalStoreConstants {
+
+ public static String SUCCESS_STRING = "DONE";
+
+ // inter activity interaction data key values
+ public static enum INTENT_EXTRA_ATTR_KEY {
+ SELECTED_CATEGORY_ID,
+ SELECTED_SUB_CATEGORY_ID,
+ SELECTED_PRODUCT_ID,
+ SELECTED_FEED_ID,
+ SELECTED_NOTIFICATION_ID,
+ SELECTED_REVIEW_ID;
+ }
+ public static String START_COMMENT_STRING = "/*";
+ public static String END_COMMENT_STRING = "*/";
+ public static enum StoreParameterKeys {
+ langId,
+ storeId,
+ type,
+ identifier,
+ catalogId
+ }
+
+ public static enum HTTP_METHODS {
+ GET, POST
+ }
+ public static enum HTTP_RESPONSE_CODES {
+ OK(200),
+ CREATED(201),
+ ACCEPTED(202),
+ MULTIPLE_CHOICES(300),
+ MOVED_PERMANENTLY(301),
+ BAD_REQUEST(400),
+ UNAUTHORIZED(401),
+ FORBIDDEN(403),
+ NOT_FOUND(404),
+ REQUEST_TIMEOUT(408);
+ HTTP_RESPONSE_CODES(int code) {
+ this.codeValue = code;
+ }
+ private int codeValue;
+
+ public static HTTP_RESPONSE_CODES getCode(int value) {
+ HTTP_RESPONSE_CODES returnValue = HTTP_RESPONSE_CODES.NOT_FOUND;
+ for(HTTP_RESPONSE_CODES code : HTTP_RESPONSE_CODES.values()) {
+ if(code.codeValue == value) {
+ returnValue = code;
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+ }
+ public static enum HTTP_REQUEST_HEADER_PROPERTIES {
+ CONNECTION("Connection"),
+ CONTENT_TYPE("Content-Type"),
+ CONTENT_DISPOSITION("Content-Disposition"),
+ CONTENT_TRANSFER_ENCODING("Content-Transfer-Encoding"),
+ CONTENT_LENGTH("Content-length");
+
+ HTTP_REQUEST_HEADER_PROPERTIES(String value) {
+ this.value = value;
+ }
+ private String value;
+
+ public String getValue() {
+ return this.value;
+ }
+ }
+
+ public static enum HTTP_HEADER_VALUES {
+ CONNECTION_KEEP_ALIVE("Keep-Alive"),
+ CONTENT_TYPE_TEXT("text/plain"),
+ CONTENT_DISPOSITION_FORM_DATA("form-data; name=\"{0}\""),
+ CONTENT_DISPOSITION_FILE_NAME("file-name=\"{0}\""),
+ CONTENT_TYPE_OCTET(" application/octet-stream"),
+ CONTENT_TYPE_MULTIPART("multipart/form-data; boundary={0}"),
+ CONTENT_TRANSFER_ENCODING_BINARY("binary");
+
+ HTTP_HEADER_VALUES(String value) {
+ this.value = value;
+ }
+ private String value;
+ public String getValue(){
+ return this.value;
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/delegate/GimbalStoreRESTServiceDelegate.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/delegate/GimbalStoreRESTServiceDelegate.java
new file mode 100644
index 0000000..ea7a1cc
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/delegate/GimbalStoreRESTServiceDelegate.java
@@ -0,0 +1,20 @@
+package com.avnet.gears.codes.gimbal.store.delegate;
+
+import android.util.Log;
+
+import com.avnet.gears.codes.gimbal.store.bean.CategoryBean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by 914889 on 2/24/15.
+ */
+public class GimbalStoreRESTServiceDelegate {
+ public static List getAllCategories() {
+ Log.d("DEBUG","Entering GimbalStoreRESTServiceDelegate.getAllCategories()");
+ List allCategoriesList = new ArrayList();
+ Log.d("DEBUG","Exiting GimbalStoreRESTServiceDelegate.getAllCategories()");
+ return allCategoriesList;
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/fragment/NavigationDrawerFragment.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/fragment/NavigationDrawerFragment.java
new file mode 100644
index 0000000..bcbcf4e
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/fragment/NavigationDrawerFragment.java
@@ -0,0 +1,307 @@
+package com.avnet.gears.codes.gimbal.store.fragment;
+
+
+import android.app.Activity;
+import android.app.ActionBar;
+import android.app.Fragment;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import com.avnet.gears.codes.gimbal.store.R;
+import com.avnet.gears.codes.gimbal.store.activity.HomeActivity;
+import com.avnet.gears.codes.gimbal.store.bean.CategoryBean;
+
+import java.util.List;
+
+/**
+ * Fragment used for managing interactions for and presentation of a navigation drawer.
+ * See the
+ * design guidelines for a complete explanation of the behaviors implemented here.
+ */
+public class NavigationDrawerFragment extends Fragment {
+
+ /**
+ * Remember the position of the selected item.
+ */
+ private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
+
+ /**
+ * Per the design guidelines, you should show the drawer on launch until the user manually
+ * expands it. This shared preference tracks this.
+ */
+ private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
+
+ /**
+ * A pointer to the current callbacks instance (the Activity).
+ */
+ private NavigationDrawerCallbacks mCallbacks;
+
+ /**
+ * Helper component that ties the action bar to the navigation drawer.
+ */
+ private ActionBarDrawerToggle mDrawerToggle;
+
+ private DrawerLayout mDrawerLayout;
+ private ListView mDrawerListView;
+ private View mFragmentContainerView;
+
+ private int mCurrentSelectedPosition = 0;
+ private boolean mFromSavedInstanceState;
+ private boolean mUserLearnedDrawer;
+
+ private String[] mCategoryTitles = new String[]{"Section 1", "Section 2", "Section 3", "Section 4"};
+
+ public NavigationDrawerFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Read in the flag indicating whether or not the user has demonstrated awareness of the
+ // drawer. See PREF_USER_LEARNED_DRAWER for details.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
+
+ if (savedInstanceState != null) {
+ mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
+ mFromSavedInstanceState = true;
+ }
+
+ // Select either the default item (0) or the last selected item.
+ selectItem(mCurrentSelectedPosition);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ // Indicate that this fragment would like to influence the set of actions in the action bar.
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mDrawerListView = (ListView) inflater.inflate(
+ R.layout.fragment_navigation_drawer, container, false);
+ mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ selectItem(position);
+ }
+ });
+ refreshDrawerListView();
+ return mDrawerListView;
+ }
+ public void refreshDrawerListView() {
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mDrawerListView.setAdapter(new ArrayAdapter(
+ getActionBar().getThemedContext(),
+ android.R.layout.simple_list_item_activated_1,
+ android.R.id.text1,
+ mCategoryTitles
+ ));
+
+ mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
+ mDrawerListView.refreshDrawableState();
+ }
+ });
+ }
+ public boolean isDrawerOpen() {
+ return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
+ }
+
+ /**
+ * Users of this fragment must call this method to set up the navigation drawer interactions.
+ *
+ * @param fragmentId The android:id of this fragment in its activity's layout.
+ * @param drawerLayout The DrawerLayout containing this fragment's UI.
+ */
+ public void setUp(int fragmentId, DrawerLayout drawerLayout, String[] categoryTitles) {
+ mFragmentContainerView = getActivity().findViewById(fragmentId);
+ mDrawerLayout = drawerLayout;
+
+ // set a custom shadow that overlays the main content when the drawer opens
+ mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
+ // set up the drawer's list view with items and click listener
+ mCategoryTitles = categoryTitles;
+ refreshDrawerListView();
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeButtonEnabled(true);
+
+ // ActionBarDrawerToggle ties together the the proper interactions
+ // between the navigation drawer and the action bar app icon.
+ mDrawerToggle = new ActionBarDrawerToggle(
+ getActivity(), /* host Activity */
+ mDrawerLayout, /* DrawerLayout object */
+ R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
+ R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
+ R.string.navigation_drawer_close /* "close drawer" description for accessibility */
+ ) {
+ @Override
+ public void onDrawerClosed(View drawerView) {
+ super.onDrawerClosed(drawerView);
+ if (!isAdded()) {
+ return;
+ }
+
+ getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
+ }
+
+ @Override
+ public void onDrawerOpened(View drawerView) {
+ super.onDrawerOpened(drawerView);
+ if (!isAdded()) {
+ return;
+ }
+
+ if (!mUserLearnedDrawer) {
+ // The user manually opened the drawer; store this flag to prevent auto-showing
+ // the navigation drawer automatically in the future.
+ mUserLearnedDrawer = true;
+ SharedPreferences sp = PreferenceManager
+ .getDefaultSharedPreferences(getActivity());
+ sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
+ }
+
+ getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
+ }
+ };
+
+ // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
+ // per the navigation drawer design guidelines.
+ if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
+ mDrawerLayout.openDrawer(mFragmentContainerView);
+ }
+
+ // Defer code dependent on restoration of previous instance state.
+ mDrawerLayout.post(new Runnable() {
+ @Override
+ public void run() {
+ mDrawerToggle.syncState();
+ }
+ });
+
+ mDrawerLayout.setDrawerListener(mDrawerToggle);
+ }
+
+ private void selectItem(int position) {
+ mCurrentSelectedPosition = position;
+ Log.d("DEBUG", "mCurrentSelectedPosition="+mCurrentSelectedPosition);
+ if (mDrawerListView != null) {
+ mDrawerListView.setItemChecked(position, true);
+ }
+ if (mDrawerLayout != null) {
+ mDrawerLayout.closeDrawer(mFragmentContainerView);
+ }
+ if (mCallbacks != null) {
+ mCallbacks.onNavigationDrawerItemSelected(position);
+ }
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ mCallbacks = (NavigationDrawerCallbacks) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mCallbacks = null;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ // Forward the new configuration the drawer toggle component.
+ mDrawerToggle.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ // If the drawer is open, show the global app actions in the action bar. See also
+ // showGlobalContextActionBar, which controls the top-left area of the action bar.
+ if (mDrawerLayout != null && isDrawerOpen()) {
+ inflater.inflate(R.menu.global, menu);
+ showGlobalContextActionBar();
+ }
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (mDrawerToggle.onOptionsItemSelected(item)) {
+ return true;
+ }
+
+ if (item.getItemId() == R.id.action_example) {
+ Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * Per the navigation drawer design guidelines, updates the action bar to show the global app
+ * 'context', rather than just what's in the current screen.
+ */
+ private void showGlobalContextActionBar() {
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+ actionBar.setTitle(R.string.app_name);
+ }
+
+ private ActionBar getActionBar() {
+ return getActivity().getActionBar();
+ }
+
+ /**
+ * Callbacks interface that all activities using this fragment must implement.
+ */
+ public static interface NavigationDrawerCallbacks {
+
+
+ /**
+ * Called when an item in the navigation drawer is selected.
+ */
+ void onNavigationDrawerItemSelected(int position);
+
+ }
+ public void setmCategoryTitles(String[] categoryTitles) {
+ this.mCategoryTitles = categoryTitles;
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/handler/HttpConnectionAsyncTask.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/handler/HttpConnectionAsyncTask.java
new file mode 100644
index 0000000..aefc353
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/handler/HttpConnectionAsyncTask.java
@@ -0,0 +1,55 @@
+package com.avnet.gears.codes.gimbal.store.handler;
+
+import android.os.AsyncTask;
+
+import com.avnet.gears.codes.gimbal.store.async.response.processor.AsyncResponseProcessor;
+import com.avnet.gears.codes.gimbal.store.client.HttpClient;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.HTTP_RESPONSE_CODES;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants.HTTP_METHODS;
+
+
+import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by 914889 on 2/24/15.
+ */
+public class HttpConnectionAsyncTask extends AsyncTask, Object> {
+
+ private String url;
+ private HTTP_METHODS httpMethod;
+ private String responseString;
+ private int responseCode;
+ private String responseType;
+ private Map parametersMap;
+ private AsyncResponseProcessor processor;
+
+ public HttpConnectionAsyncTask(HTTP_METHODS http_method, String url,
+ Map parametersMap, AsyncResponseProcessor processor){
+ this.processor = processor;
+ this.httpMethod = http_method;
+ this.url = url;
+ this.parametersMap = parametersMap;
+ }
+
+ @Override
+ protected String doInBackground(String... params) {
+ try {
+ HttpURLConnection con = HttpClient.getHttpGetConnection(this.url, parametersMap);
+ this.responseString = HttpClient.getResponseString(con);
+ this.responseCode = con.getResponseCode();
+ // Log.d("DEBUG", "String response code = " + this.responseCode );
+ // Log.d("DEBUG", "Response = " + responseString);
+ this.processor.doProcess(HTTP_RESPONSE_CODES.getCode(this.responseCode), this.responseString);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return GimbalStoreConstants.SUCCESS_STRING;
+ }
+ protected void onPostExecute(String page)
+ {
+ //onPostExecute call the response handler's process
+ }
+ }
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/handler/ImageResponseAsyncTask.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/handler/ImageResponseAsyncTask.java
new file mode 100644
index 0000000..daeac5d
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/handler/ImageResponseAsyncTask.java
@@ -0,0 +1,43 @@
+package com.avnet.gears.codes.gimbal.store.handler;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * Created by 914889 on 3/4/15.
+ */
+public class ImageResponseAsyncTask extends AsyncTask, Object> {
+ private String imageUrl;
+ private ImageView imageView;
+ private ImageButton imageButton;
+
+ public ImageResponseAsyncTask(String imageUrl, ImageView imageView, ImageButton imageButton) {
+ this.imageUrl = imageUrl;
+ this.imageView = imageView;
+ this.imageButton = imageButton;
+ }
+
+ @Override
+ protected Object doInBackground(String... params) {
+ try {
+ Bitmap bitmap = BitmapFactory.decodeStream((InputStream) new URL(imageUrl).getContent());
+ if(imageButton != null) {
+ imageButton.setImageBitmap(bitmap);
+ } else if(imageView != null) {
+ imageButton.setImageBitmap(bitmap);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return GimbalStoreConstants.SUCCESS_STRING;
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/NotificationUtil.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/NotificationUtil.java
new file mode 100644
index 0000000..b51cf30
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/NotificationUtil.java
@@ -0,0 +1,53 @@
+package com.avnet.gears.codes.gimbal.store.utils;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+
+import com.avnet.gears.codes.gimbal.store.bean.NotificationActionBean;
+
+import java.util.List;
+
+/**
+ * Created by 914889 on 2/27/15.
+ */
+public class NotificationUtil {
+
+ public static void notify(Context context, Intent targetIntent,
+ String contentText, String notificationTitle, int resourceIcon,
+ boolean autoCancel, List actionsBeanList) {
+ // prepare intent which is triggered if the
+ // notification is selected
+
+ PendingIntent pIntent = PendingIntent.getActivity(context, 0, targetIntent, 0);
+
+ // build notification
+ // the addAction re-use the same intent to keep the example short
+ Notification.Builder builder = new Notification.Builder(context)
+ .setContentTitle(notificationTitle)
+ .setContentText(contentText)
+ .setSmallIcon(resourceIcon)
+ .setContentIntent(pIntent)
+ .setAutoCancel(autoCancel);
+ // dynamically add sub actions, if any
+ if(actionsBeanList != null) {
+ for(NotificationActionBean actionBean : actionsBeanList){
+ builder.addAction(actionBean.getDrawableIcon(),
+ actionBean.getActionTitle(),
+ actionBean.getTargetActionPendingIntent());
+ }
+ }
+
+ // build to notifications once we set all teh parameters
+ Notification n = builder.build();
+
+ // create a notification manager from the calling context
+ NotificationManager notificationManager =
+ (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ // send notification
+ notificationManager.notify(0, n);
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/ServerURLUtil.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/ServerURLUtil.java
new file mode 100644
index 0000000..7225d81
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/ServerURLUtil.java
@@ -0,0 +1,43 @@
+package com.avnet.gears.codes.gimbal.store.utils;
+
+import android.content.res.Resources;
+
+import com.avnet.gears.codes.gimbal.store.R;
+import com.avnet.gears.codes.gimbal.store.constant.GimbalStoreConstants;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by 914889 on 3/4/15.
+ */
+public class ServerURLUtil {
+ private static String SEPARATOR_SLASH = "/";
+
+ public static String getStoreServletServerURL(Resources resource) {
+ StringBuilder activeServerURL = new StringBuilder();
+ activeServerURL.append(resource.getString(R.string.SERVER_PROTOCOL));
+ activeServerURL.append(resource.getString(R.string.STORE_SERVICE_HOST));
+ activeServerURL.append(resource.getString(R.string.STORE_SERVLET_CONTEXT_ROOT));
+ activeServerURL.append(resource.getString(R.string.MOBILE_ACCESS_CONTROLLER_SERVLET));
+ return activeServerURL.toString();
+ }
+ public static String getAbsoluteUrlFor(Resources resource, String relativeURL){
+ StringBuilder activeServerURL = new StringBuilder();
+ activeServerURL.append(resource.getString(R.string.SERVER_PROTOCOL));
+ activeServerURL.append(resource.getString(R.string.STORE_SERVICE_HOST));
+ if(!relativeURL.startsWith(SEPARATOR_SLASH)) {
+ activeServerURL.append(SEPARATOR_SLASH);
+ }
+ activeServerURL.append(relativeURL);
+ return activeServerURL.toString();
+ }
+ public static Map getBasicConfigParamsMap(Resources resource) {
+ Map paramsMap = new HashMap();
+ paramsMap.put(GimbalStoreConstants.StoreParameterKeys.langId.toString(),
+ String.valueOf(resource.getString(R.string.ACTIVE_STORE_LANG_ID)));
+ paramsMap.put(GimbalStoreConstants.StoreParameterKeys.storeId.toString(),
+ String.valueOf(resource.getString(R.string.ACTIVE_STORE_ID)));
+ return paramsMap;
+ }
+}
diff --git a/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/TypeConversionUtil.java b/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/TypeConversionUtil.java
new file mode 100644
index 0000000..79d1eb7
--- /dev/null
+++ b/app/src/main/java/com/avnet/gears/codes/gimbal/store/utils/TypeConversionUtil.java
@@ -0,0 +1,26 @@
+package com.avnet.gears.codes.gimbal.store.utils;
+
+import android.util.Log;
+
+import com.avnet.gears.codes.gimbal.store.bean.CategoryBean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by 914889 on 3/4/15.
+ */
+public class TypeConversionUtil {
+
+ public static String[] getCategoryTitleList(List categoryBeanList) {
+ List categoryTitleList = new ArrayList<>();
+ if(categoryBeanList != null && !categoryBeanList.isEmpty()) {
+ for(CategoryBean categoryBean : categoryBeanList){
+ categoryTitleList.add(categoryBean.getName());
+ }
+ }
+ Log.d("DEBUG", categoryTitleList.toArray(new String[]{}).toString());
+ return categoryTitleList.toArray(new String[]{});
+ }
+
+}
diff --git a/app/src/main/res/drawable-hdpi/drawer_shadow.9.png b/app/src/main/res/drawable-hdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..236bff5
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/drawer_shadow.9.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_drawer.png b/app/src/main/res/drawable-hdpi/ic_drawer.png
new file mode 100644
index 0000000..c59f601
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_drawer.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-mdpi/drawer_shadow.9.png b/app/src/main/res/drawable-mdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..ffe3a28
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/drawer_shadow.9.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_drawer.png b/app/src/main/res/drawable-mdpi/ic_drawer.png
new file mode 100644
index 0000000..1ed2c56
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_drawer.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png b/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..fabe9d9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_drawer.png b/app/src/main/res/drawable-xhdpi/ic_drawer.png
new file mode 100644
index 0000000..a5fa74d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_drawer.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png b/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..b91e9d7
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_drawer.png b/app/src/main/res/drawable-xxhdpi/ic_drawer.png
new file mode 100644
index 0000000..9c4685d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_drawer.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/layout/activity_feed_list.xml b/app/src/main/res/layout/activity_feed_list.xml
new file mode 100644
index 0000000..6dae774
--- /dev/null
+++ b/app/src/main/res/layout/activity_feed_list.xml
@@ -0,0 +1,4 @@
+
diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml
new file mode 100644
index 0000000..1af536f
--- /dev/null
+++ b/app/src/main/res/layout/activity_home.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_subcategory_home.xml b/app/src/main/res/layout/activity_subcategory_home.xml
new file mode 100644
index 0000000..3509b84
--- /dev/null
+++ b/app/src/main/res/layout/activity_subcategory_home.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_feed_list.xml b/app/src/main/res/layout/fragment_feed_list.xml
new file mode 100644
index 0000000..8852a47
--- /dev/null
+++ b/app/src/main/res/layout/fragment_feed_list.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
new file mode 100644
index 0000000..1ab4b99
--- /dev/null
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_navigation_drawer.xml b/app/src/main/res/layout/fragment_navigation_drawer.xml
new file mode 100644
index 0000000..c05742d
--- /dev/null
+++ b/app/src/main/res/layout/fragment_navigation_drawer.xml
@@ -0,0 +1,5 @@
+
diff --git a/app/src/main/res/layout/view_subcategory_list_item.xml b/app/src/main/res/layout/view_subcategory_list_item.xml
new file mode 100644
index 0000000..bc86d80
--- /dev/null
+++ b/app/src/main/res/layout/view_subcategory_list_item.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/global.xml b/app/src/main/res/menu/global.xml
new file mode 100644
index 0000000..184ad2b
--- /dev/null
+++ b/app/src/main/res/menu/global.xml
@@ -0,0 +1,4 @@
+
diff --git a/app/src/main/res/menu/menu_feed_list.xml b/app/src/main/res/menu/menu_feed_list.xml
new file mode 100644
index 0000000..6a9a7f3
--- /dev/null
+++ b/app/src/main/res/menu/menu_feed_list.xml
@@ -0,0 +1,6 @@
+
diff --git a/app/src/main/res/menu/menu_home.xml b/app/src/main/res/menu/menu_home.xml
new file mode 100644
index 0000000..1bfb9bf
--- /dev/null
+++ b/app/src/main/res/menu/menu_home.xml
@@ -0,0 +1,7 @@
+
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..dba3c41
--- /dev/null
+++ b/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,5 @@
+
+
+
+
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/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..074e7a0
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+
+ 240dp
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..937bbda
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,27 @@
+
+
+
+ TheGimbalStore
+ Section 1
+ Section 2
+ Section 3
+ Open navigation drawer
+ Close navigation drawer
+ Example action
+ Settings
+
+
+
+ http://
+ 192.168.3.233
+ /webapp/wcs/stores/servlet
+ /F8app
+ 10151
+ -1
+
+
+ FeedListActivity
+
+ Hello world!
+
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..ff6c9d2
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..6356aab
--- /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.0.0'
+
+ // 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..8c0fb64
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..0c71e76
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,164 @@
+#!/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
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# 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\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+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"`
+
+ # 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..aec9973
--- /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'