Skip to content

Instantly share code, notes, and snippets.

@vschmidt94
Created May 24, 2015 16:00
Show Gist options
  • Save vschmidt94/d2366881a9c06dbce379 to your computer and use it in GitHub Desktop.
Save vschmidt94/d2366881a9c06dbce379 to your computer and use it in GitHub Desktop.
Android get and parse nested JSON
package org.corvallisrecycles.recycleapp;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.corvallisrecycles.recycleapp.dom.*;
import org.corvallisrecycles.recycleapp.DBContract;
public class SyncDBActivity extends ActionBarActivity {
// set up a db service
private DBService myDBManager;
private static final String theURL = "http://www.corvallisrecycles.org/api/interface.php?cmp=1&cat=1&cmpcat=1";
private ProgressDialog pDialog;
private TextView textView;
// JSON Node Names
public static final String TAG_TABLES = "Database"; // poor choice of works is
public static final String TAG_COMPANIES_TABLE = "Companies";
public static final String TAG_CATEGORIES_TABLE = "Categories";
public static final String TAG_CMP_CAT_TABLE = "CompanyCategories";
public static final String TAG_CMP_ID = "cmp_id";
public static final String TAG_CMP_NAME = "cmp_name";
public static final String TAG_CMP_ADDRESS_1 = "cmp_address1";
public static final String TAG_CMP_ADDRESS_2 = "cmp_address2";
public static final String TAG_CMP_CITY = "cmp_city";
public static final String TAG_CMP_STATE = "cmp_state";
public static final String TAG_CMP_ZIP = "cmp_zip";
public static final String TAG_CMP_PHONE = "cmp_phone";
public static final String TAG_CMP_EMAIL = "cmp_email";
public static final String TAG_CMP_WEBSITE = "cmp_website";
public static final String TAG_CMP_NOTES = "cmp_notes";
public static final String TAG_CMP_RECYCLE_FLAG = "cmp_recycle_flag";
public static final String TAG_CMP_REPAIR_FLAG = "cmp_repair_flag";
public static final String TAG_CAT_ID = "cat_id";
public static final String TAG_CAT_NAME = "cat_name";
public static final String TAG_CAT_DESC = "cat_descr";
public static final String TAG_CAT_NOTES = "cat_notes";
public static final String TAG_CMPCAT_CMP_ID = "cmp_id";
public static final String TAG_CMPCAT_CAT_ID = "cat_id";
public static final String TAG_CMPCAT_NOTES = "comp_cat_notes";
// TABLE NAMES
public static final String TABLE_CMP = "Companies";
public static final String TABLE_CAT = "Categories";
public static final String TABLE_CMP_CAT = "CompanyCategories";
// TABLE COLUMNS
public static final String CMP_ID = "cmp_id";
public static final String CMP_NAME = "cmp_name";
public static final String CMP_ADDR1 = "cmp_address_1";
public static final String CMP_ADDR2 = "cmp_address_2";
public static final String CMP_CITY = "cmp_city";
public static final String CMP_STATE = "cmp_state";
public static final String CMP_ZIP = "cmp_zip";
public static final String CMP_PHONE = "cmp_phone";
public static final String CMP_WEBSITE = "cmp_email";
public static final String CMP_EMAIL = "cmp_website";
public static final String CMP_NOTES = "cmp_notes";
public static final String CMP_RECYCLE = "recycle_flag";
public static final String CMP_REPAIR = "repair_flag";
public static final String CAT_ID = "cat_id";
public static final String CAT_NAME = "cat_name";
public static final String CAT_DESC = "cat_descr";
public static final String CAT_NOTES = "cat_notes";
public static final String CMP_CAT_CMP_ID = "cmp_id";
public static final String CMP_CAT_CAT_ID = "cat_id";
public static final String CMP_CAT_NOTES = "cmp_cat_notes";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync_db);
// Test for network connection
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isConnected() ) {
// we have network availability
// get the JSON from Database
new GetWebServiceData().execute();
}
else
{
// notify user of no network connection
Context context = getApplicationContext();
CharSequence msg = "No internet connection available, can not load data";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, msg, duration);
toast.show();
}
}
@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_sync_db, 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);
}
/**
* Subclass GetWebServiceData uses HTTP Async Task to run on background thread.
*/
private class GetWebServiceData extends AsyncTask<Void, Void, Void> {
// help from http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
// and developer.android.com/training/basics/network-ops/connecting.html
// Progress bar dialog
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(SyncDBActivity.this);
pDialog.setMessage("Syncing Data....");
pDialog.setCancelable(false);
pDialog.show();
} /* onPreExecute */
@Override
protected Void doInBackground(Void... arg0) {
try {
// Get the information
downloadUrl(theURL);
} catch (IOException e) {
textView.setText("Unable to retrieve web page. URL may be invalid");
}
return null;
} /* End doInBackground */
//onPostExecute dismisses the progress bar
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing()) {
pDialog.dismiss();
}
// notify user the sync is done
Context context = getApplicationContext();
CharSequence msg = "Sync has finished. OK to return to App (use Back Button)";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, msg, duration);
toast.show();
} /* onPostExecute */
/** Given a URL, establishes a HttpUrlConnection and retrieves the content as an InputStream,
* which it parses into the HashMap structure used to fill the ListView.
*/
private void downloadUrl(String myUrl) throws IOException {
InputStream is = null;
String contentString = null;
URL url = new URL(myUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// flush the tables and set up schema
// set up a sqlite schema
DBHelper dbHelper = new DBHelper(getApplicationContext());
dbHelper.recreate();
SQLiteDatabase db = dbHelper.getWritableDatabase();
//myDBManager = new DBService(dbHelper.getWritableDatabase());
Log.d("DBManager", "Schema has been built");
try {
// Set Timeouts
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Start the query
conn.connect();
int response = conn.getResponseCode();
if (response == 200) // if got actual data
{
is = conn.getInputStream();
// Convert the InputStream into a string
contentString = InputStreamToString(is);
}
// Makes sure InputStream's closed & connection's disconnected after app's finished using it
} finally {
if (is != null) {
is.close();
}
conn.disconnect();
}
// Take the string that was returned and parse out component tables to make the HashMaps
if (contentString != null)
{
// ArrayList hashmaps representing Database Rows enroute to SQLite Store
ArrayList<HashMap<String, String>> companyList = new ArrayList<>();
ArrayList<HashMap<String, String>> categoryList = new ArrayList<>();
ArrayList<HashMap<String, String>> companyCategoryList = new ArrayList();
// Parse the JSON
try {
JSONObject webserviceJSON = new JSONObject(contentString);
Log.d("SyncDB", "webserviceJSON = " + webserviceJSON.toString().substring(0,30));
JSONObject allTablesJSON = webserviceJSON.getJSONObject(TAG_TABLES);
// break out component tables as their own JSONArrays
JSONArray companyTableJSONArray = allTablesJSON.getJSONArray(TAG_COMPANIES_TABLE);
JSONArray categoryTableJSONArray = allTablesJSON.getJSONArray(TAG_CATEGORIES_TABLE);
JSONArray compCatTableJSONArray = allTablesJSON.getJSONArray(TAG_CMP_CAT_TABLE);
Log.d("SyncDB", companyTableJSONArray.toString().substring(0, 30));
Log.d("SyncDB", "Start parsing companies");
// looping through all companies
List<DBContract.Companies> companies = new ArrayList<>();
for (int i = 0; i < companyTableJSONArray.length(); i++) {
JSONObject childCompany = companyTableJSONArray.getJSONObject(i);
// Use Content Values for SQLite
ContentValues values = new ContentValues();
values.put(CMP_ID, childCompany.getInt(TAG_CMP_ID));
values.put(CMP_NAME, childCompany.getString(TAG_CMP_NAME));
values.put(CMP_ADDR1, childCompany.getString(TAG_CMP_ADDRESS_1));
values.put(CMP_ADDR2, childCompany.getString(TAG_CMP_ADDRESS_2));
values.put(CMP_CITY, childCompany.getString(TAG_CMP_CITY));
values.put(CMP_STATE, childCompany.getString(TAG_CMP_STATE));
values.put(CMP_ZIP, childCompany.getString(TAG_CMP_ZIP));
values.put(CMP_PHONE, childCompany.getString(TAG_CMP_PHONE));
values.put(CMP_EMAIL, childCompany.getString(TAG_CMP_EMAIL));
values.put(CMP_WEBSITE, childCompany.getString(TAG_CMP_WEBSITE));
values.put(CMP_NOTES, childCompany.getString(TAG_CMP_ID));
values.put(CMP_RECYCLE, childCompany.getInt(TAG_CMP_RECYCLE_FLAG));
values.put(CMP_REPAIR, childCompany.getInt(TAG_CMP_REPAIR_FLAG));
// insert the company record into the database
long newRowId;
newRowId = db.insert(TABLE_CMP, null, values);
Log.d("SyncDB", "Added Company Record " + newRowId);
}
// looping through all the categories
for (int i=0; i < categoryTableJSONArray.length(); i++) {
JSONObject childCategory = categoryTableJSONArray.getJSONObject(i);
// Use Content Values for SQLite
ContentValues values = new ContentValues();
values.put(CAT_ID, childCategory.getInt(TAG_CAT_ID));
values.put(CAT_NAME, childCategory.getString(TAG_CAT_NAME));
values.put(CAT_DESC, childCategory.getString(TAG_CAT_DESC));
values.put(CAT_NOTES, childCategory.getString(TAG_CAT_NOTES));
// insert the company record into the database
long newRowId;
newRowId = db.insert(TABLE_CAT, null, values);
Log.d("SyncDB", "Added Category Record " + newRowId);
}
// looping through all the companycategory joins
for(int i=0; i < compCatTableJSONArray.length(); i++) {
JSONObject compCatChild = compCatTableJSONArray.getJSONObject(i);
// use Content Values for SQLite
ContentValues values = new ContentValues();
values.put(CMP_CAT_CMP_ID, compCatChild.getInt(TAG_CMPCAT_CMP_ID));
values.put(CMP_CAT_CAT_ID, compCatChild.getInt(TAG_CMPCAT_CAT_ID));
values.put(CMP_CAT_NOTES, compCatChild.getString(TAG_CMPCAT_NOTES));
// get out the parts
String cmpcat_cmp_id = compCatChild.getString(TAG_CMPCAT_CMP_ID);
String cmpcat_cat_id = compCatChild.getString(TAG_CMPCAT_CAT_ID);
String cmpcat_notes = compCatChild.getString(TAG_CMPCAT_NOTES);
// insert the company record into the database
long newRowId;
newRowId = db.insert(TABLE_CMP_CAT, null, values);
Log.d("SyncDB", "Added Company-Category Record " + newRowId);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
} /* end DownloadURL() */
} /* End GetWebService Data */
public static String InputStreamToString(InputStream is1)
{
BufferedReader rd = new BufferedReader(new InputStreamReader(is1), 4096);
String line;
StringBuilder sb = new StringBuilder();
try {
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
} catch (IOException e) {
e.printStackTrace();
}
String contentOfMyInputStream = sb.toString();
return contentOfMyInputStream;
} /* End InputStreamToString */
private class CreateOrUpdateSchemaTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void aLong) {
Log.d("Schema", "Schema creation complete.");
}
}
} /* End SyncDBActivity Class */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment