diff --git "a/c:\\user.json" "b/c:\\user.json"
new file mode 100644
index 0000000..ec904ed
--- /dev/null
+++ "b/c:\\user.json"
@@ -0,0 +1 @@
+{"name":"mkyong","age":29,"messages":["msg 1","msg 2","msg 3"]}
\ No newline at end of file
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index ea076f1..74a8490 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -3,6 +3,9 @@
package="nyc.c4q"
android:versionCode="2"
android:versionName="1.0.0-SNAPSHOT">
+
+
+
extends ArrayAdapter {
+ TextView textLog;
+ // View lookup cache
+ private static class ViewHolder {
+ LinearLayout background;
+
+ }
+
+ public ColorAdapter(Context context, int layout, ArrayList colors, TextView textLog) {
+ super(context, layout, colors);
+ this.textLog = textLog;
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ // Get the data item for this position
+ String color = getItem(position);
+
+ // Inflate the view
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ viewHolder = new ViewHolder();
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ convertView = inflater.inflate(R.layout.custom_list_item, parent, false);
+ viewHolder.background = (LinearLayout) convertView.findViewById(R.id.background);
+ convertView.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+
+ // Set view background color
+ viewHolder.background.setBackgroundColor(Color.parseColor((java.lang.String) color));
+
+ return convertView;
+ }
+}
diff --git a/src/main/java/nyc/c4q/HttpUtil.java b/src/main/java/nyc/c4q/HttpUtil.java
new file mode 100644
index 0000000..47d8844
--- /dev/null
+++ b/src/main/java/nyc/c4q/HttpUtil.java
@@ -0,0 +1,95 @@
+package nyc.c4q;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import com.squareup.okhttp.Callback;
+import com.squareup.okhttp.MediaType;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.RequestBody;
+import com.squareup.okhttp.Response;
+
+import java.io.IOException;
+
+import okio.BufferedSink;
+
+public class HttpUtil {
+
+ private OkHttpClient client;
+ private Request.Builder builder;
+
+ public void get(String url, HttpCallback cb) {
+ call("GET", url, cb);
+ }
+
+ public void post(String url, HttpCallback cb) {
+ call("POST", url, cb);
+ }
+
+ private void call(String method, String url, final HttpCallback cb) {
+ Request request = builder.url(url).method(method, method.equals("GET") ? null : new RequestBody() {
+
+ @Override
+ public MediaType contentType() {
+ return null;
+ }
+
+ @Override
+ public void writeTo(BufferedSink sink) throws IOException {
+
+ }
+ }).build();
+
+ client.newCall(request).enqueue(new Callback() {
+ Handler mainHandler = new Handler(Looper.getMainLooper());
+
+ @Override
+ public void onFailure(Request request,final IOException throwable) {
+ mainHandler.post(new Runnable() {
+
+ @Override
+ public void run() {
+ cb.onFailure(null, throwable);
+ }
+ });
+
+ }
+
+ @Override
+ public void onResponse(final Response response) throws IOException {
+ mainHandler.post(new Runnable() {
+
+ @Override
+ public void run() {
+ if (!response.isSuccessful()) {
+ cb.onFailure(response, null);
+ return;
+ }
+ cb.onSuccess(response);
+ }
+ });
+
+ }
+ });
+ }
+
+
+ public interface HttpCallback {
+
+ /**
+ * called when the server response was not 2xx or when an exception was thrown in the process
+ * @param response - in case of server error (4xx, 5xx) this contains the server response
+ * in case of IO exception this is null
+ * @param throwable - contains the exception. in case of server error (4xx, 5xx) this is null
+ */
+ public void onFailure(Response response, IOException throwable);
+
+ /**
+ * contains the server response
+ * @param response
+ */
+ public void onSuccess(Response response);
+ }
+
+}
diff --git a/src/main/java/nyc/c4q/JSONActivity.java b/src/main/java/nyc/c4q/JSONActivity.java
index e2ca42f..b06e8e9 100644
--- a/src/main/java/nyc/c4q/JSONActivity.java
+++ b/src/main/java/nyc/c4q/JSONActivity.java
@@ -2,27 +2,33 @@
import android.app.Activity;
import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import com.google.gson.stream.JsonWriter;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.FileReader;
-import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
-import java.util.Scanner;
import nyc.c4q.json.Zipcode;
public class JSONActivity extends Activity {
public List zipcodes;
+ public Zipcode zipcode;
+ Gson gson;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -30,10 +36,11 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_json);
zipcodes = new ArrayList();
+ gson = new Gson();
- Button savejson = (Button) findViewById(R.id.savejson);
- Button loadjson = (Button) findViewById(R.id.loadjson);
- Button addjson = (Button) findViewById(R.id.addjson);
+ final Button savejson = (Button) findViewById(R.id.savejson);
+ final Button loadjson = (Button) findViewById(R.id.loadjson);
+ final Button addjson = (Button) findViewById(R.id.addjson);
final TextView _id = (TextView) findViewById(R.id.field_idvalue);
final TextView pop = (TextView) findViewById(R.id.fieldpopvalue);
@@ -45,6 +52,20 @@ protected void onCreate(Bundle savedInstanceState) {
addjson.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+
+ // build zipcode
+ String _idS = _id.getText().toString();
+ String cityS = city.getText().toString();
+ double latS = Double.valueOf(_lat.getText().toString());
+ double longS = Double.valueOf(_long.getText().toString());
+ double[] location = {latS, longS};
+ String stateS = state.getText().toString();
+ int popS = Integer.valueOf(pop.getText().toString());
+
+ Zipcode zip = new Zipcode(_idS, cityS, location, popS, stateS);
+
+ // add it to the list
+ zipcodes.add(zip);
}
});
@@ -53,6 +74,14 @@ public void onClick(View v) {
public void onClick(View v) {
File directory = getExternalCacheDir();
File file = new File(directory, "zipcodes.json");
+ try {
+ FileOutputStream fout = new FileOutputStream(file);
+ writeJsonStream(fout, zipcodes);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+
}
});
@@ -60,9 +89,62 @@ public void onClick(View v) {
loadjson.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- File directory = getExternalCacheDir();
- File file = new File(directory, "zipcodes.json");
+ loadJson();
}
});
}
+
+ public void loadJson() {
+
+ File directory = getExternalCacheDir();
+ File file = new File(directory, "zipcodes.json");
+ JsonParser parser = new JsonParser();
+ JsonArray jsonArray = null;
+ try {
+ jsonArray = (JsonArray) parser.parse(new FileReader(file));
+ populateList(jsonArray);
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void populateList(JsonArray jsonArray) {
+ for (JsonElement zipcode : jsonArray) {
+ zipcodes.add(gson.fromJson(zipcode, Zipcode.class));
+ }
+ }
+
+ public void writeJsonStream(OutputStream out, List zipcodes) throws IOException {
+ JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
+ writeMessagesArray(writer, zipcodes);
+ writer.close();
+ }
+
+ public void writeMessagesArray(JsonWriter writer, List zipcodes) throws IOException {
+ writer.beginArray();
+ for (Zipcode zipcode : zipcodes) {
+ writeMessage(writer, zipcode);
+ }
+ writer.endArray();
+ }
+
+ public void writeMessage(JsonWriter writer, Zipcode message) throws IOException {
+ writer.beginObject();
+ writer.name("_id").value(message.get_id());
+ writer.name("city").value(message.getCity());
+ writer.name("loc");
+ writeDoublesArray(writer, message.getLoc());
+ writer.name("pop").value(message.getPop());
+ writer.name("state").value(message.getState());
+ writer.endObject();
+ }
+
+
+ public void writeDoublesArray(JsonWriter writer, double[] loc) throws IOException {
+ writer.beginArray();
+ writer.value(loc[0]);
+ writer.value(loc[1]);
+ writer.endArray();
+ }
}
diff --git a/src/main/java/nyc/c4q/ListViewActivity.java b/src/main/java/nyc/c4q/ListViewActivity.java
index 78104c6..68350ae 100644
--- a/src/main/java/nyc/c4q/ListViewActivity.java
+++ b/src/main/java/nyc/c4q/ListViewActivity.java
@@ -2,8 +2,16 @@
import android.app.Activity;
import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.EditText;
+import android.widget.ListView;
import android.widget.TextView;
+import java.util.ArrayList;
+
public class ListViewActivity extends Activity {
public static final String[] COLORS = {
@@ -18,12 +26,78 @@ public class ListViewActivity extends Activity {
"#fa5e5b",
"#bf538d"
};
+ public ArrayList colors;
public TextView textLog;
+ public ListView listView;
+ public EditText adapterCount;
+ public int count;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview);
textLog = (TextView) findViewById(R.id.textLog);
+ adapterCount = (EditText) findViewById(R.id.adapterCount);
+ count = COLORS.length;
+ colors = getColors(count);
+
+ final ColorAdapter colorsAdapter =
+ new ColorAdapter<>(this, R.layout.custom_list_item, colors, textLog);
+
+ listView = (ListView) findViewById(R.id.list);
+ listView.setAdapter(colorsAdapter);
+ listView.setItemsCanFocus(true);
+ listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ textLog.setText("You clicked on Item(position=" + position + ", color=" + ListViewActivity.COLORS[position] + ")");
+ }
+
+ });
+
+ adapterCount.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void afterTextChanged(Editable s) {}
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start,
+ int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start,
+ int before, int count) {
+ if (isValidInput(s.toString())) {
+ count = Integer.valueOf(s.toString());
+ colors = getColors(count);
+ colorsAdapter.clear();
+ colorsAdapter.addAll(colors);
+ }
+ }
+ });
+
+ }
+
+ public ArrayList getColors(int count) {
+ ArrayList colors = new ArrayList();
+ for (int i = 0; i < count; i++) {
+ colors.add(COLORS[i % 10]);
+ }
+
+ return colors;
+ }
+
+ public boolean isValidInput(String input) {
+ try {
+ Integer.parseInt(input);
+ } catch(NumberFormatException e) {
+ return false;
+ } catch(NullPointerException e) {
+ return false;
+ }
+ // only got here if we didn't return false
+ return true;
}
+
}
diff --git a/src/main/java/nyc/c4q/NetworkActivity.java b/src/main/java/nyc/c4q/NetworkActivity.java
index 3604cfc..df8f836 100644
--- a/src/main/java/nyc/c4q/NetworkActivity.java
+++ b/src/main/java/nyc/c4q/NetworkActivity.java
@@ -4,30 +4,23 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
-import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
-import com.squareup.okhttp.FormEncodingBuilder;
-import com.squareup.okhttp.HttpUrl;
-import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.Request;
-import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
-import java.io.BufferedInputStream;
-import java.io.DataOutputStream;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import java.io.BufferedReader;
+import java.io.IOException;
import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayList;
+import java.io.InputStreamReader;
public class NetworkActivity extends Activity {
- // Fields ===========================
-
public TextView httptextlog;
public Button httpbinget;
public Button httpbingetokhttp;
@@ -36,8 +29,6 @@ public class NetworkActivity extends Activity {
public Button cleartextlog;
final public String urlParams = "custname=james+dean&custtel=347-841-6090&custemail=hello%40c4q.nyc&size=small&topping=cheese&delivery=18%3A15&comments=Leave+it+by+the+garage+door.+Don't+ask+any+questions.";
- // Code ===========================
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -50,6 +41,9 @@ protected void onCreate(Bundle savedInstanceState) {
httptextlog = (TextView) findViewById(R.id.httptextlog);
httptextlog.setMovementMethod(new ScrollingMovementMethod());
+ final String url = String.format("https://httpbin.org/get?%s", urlParams);
+
+ // TODO: works when activity runs on phone, but RuntimeException when running through test??
/*
The goal is to use AsyncTasks here.
Shortcut to create URL in Java:
@@ -73,15 +67,35 @@ protected void onCreate(Bundle savedInstanceState) {
https://httpbin.org/post
*/
+
httpbinget.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+ new AsyncGet().execute(url);
+
}
});
httpbingetokhttp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+ try {
+ final String url = String.format("https://httpbin.org/get?%s", urlParams);
+ HttpUtil httpUtil = new HttpUtil();
+ httpUtil.get(url, new HttpUtil.HttpCallback() {
+ @Override
+ public void onFailure(Response response, IOException throwable) {
+ // handle failure
+ }
+
+ @Override
+ public void onSuccess(Response response) {
+ httptextlog.setText(response.toString());
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
});
@@ -94,6 +108,8 @@ public void onClick(View v) {
httpbinpostokhttp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+
+
}
});
@@ -104,4 +120,36 @@ public void onClick(View v) {
}
});
}
+
+ private class AsyncGet extends AsyncTask {
+ @Override
+ protected String doInBackground(String... urls) {
+ String response = "";
+ for (String url : urls) {
+ DefaultHttpClient client = new DefaultHttpClient();
+ HttpGet httpGet = new HttpGet(url);
+ try {
+ HttpResponse execute = client.execute(httpGet);
+ InputStream content = execute.getEntity().getContent();
+
+ BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
+ String s = "";
+ while ((s = buffer.readLine()) != null) {
+ response += s;
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return response;
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ httptextlog.setText(result);
+ }
+ }
}
+
+
diff --git a/src/main/java/nyc/c4q/NotificationActivity.java b/src/main/java/nyc/c4q/NotificationActivity.java
index f1f56ad..6e0a22b 100644
--- a/src/main/java/nyc/c4q/NotificationActivity.java
+++ b/src/main/java/nyc/c4q/NotificationActivity.java
@@ -1,8 +1,10 @@
package nyc.c4q;
import android.app.Activity;
+import android.app.Notification;
import android.app.NotificationManager;
import android.os.Bundle;
+import android.view.View;
import android.widget.Button;
public class NotificationActivity extends Activity {
@@ -25,5 +27,56 @@ protected void onCreate(Bundle savedInstanceState) {
Button dismisspermanentnotification = (Button) findViewById(R.id.dismisspermanentnotification);
Button buttonnotification = (Button) findViewById(R.id.buttonnotification);
+ autocancelnotification.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Notification.Builder mBuilder =
+ new Notification.Builder(getBaseContext())
+ .setSmallIcon(R.drawable.c4qfavicon)
+ .setContentTitle("default@c4q.nyc")
+ .setContentText("Touch me to dismiss me!");
+ Notification n = mBuilder.build();
+ n.flags = Notification.FLAG_AUTO_CANCEL;
+ notificationManager.notify(0, n);
+
+ }
+ });
+
+ swipenotification.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Notification.Builder mBuilder =
+ new Notification.Builder(getBaseContext())
+ .setSmallIcon(R.drawable.c4qfavicon)
+ .setContentTitle("swipe@c4q.nyc")
+ .setContentText("Swipe right if you want to meet me. Otherwise, I'm not going away.");
+ Notification n = mBuilder.build();
+ n.flags = 0;
+ notificationManager.notify(1, n);
+ }
+ });
+
+ permanentnotification.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Notification.Builder mBuilder =
+ new Notification.Builder(getBaseContext())
+ .setSmallIcon(R.drawable.c4qfavicon)
+ .setOngoing(true)
+ .setContentTitle("permanent@c4q.nyc")
+ .setContentText("I'm staying planted right here.");
+ Notification n = mBuilder.build();
+ notificationManager.notify(2, n);
+ }
+ });
+
+ dismisspermanentnotification.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ notificationManager.cancel(2);
+ }
+ });
+
}
}
diff --git a/src/main/java/nyc/c4q/json/Zipcode.java b/src/main/java/nyc/c4q/json/Zipcode.java
index 6d4761f..95261c0 100644
--- a/src/main/java/nyc/c4q/json/Zipcode.java
+++ b/src/main/java/nyc/c4q/json/Zipcode.java
@@ -1,4 +1,57 @@
package nyc.c4q.json;
public class Zipcode {
+ public String _id;
+ public String city;
+ public String state;
+ public int pop;
+ public double[] loc;
+
+ public Zipcode(String _id, String city, double[] location, int pop, String state) {
+ this._id = _id;
+ this.city = city;
+ this.state = state;
+ this.loc = location;
+ this.pop = pop;
+ }
+
+ public double[] getLoc() {
+ return loc;
+ }
+
+ public void setLocation(double[] location) {
+ this.loc = location;
+ }
+
+ public String get_id() {
+ return _id;
+ }
+
+ public void set_id(String _id) {
+ this._id = _id;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public int getPop() {
+ return pop;
+ }
+
+ public void setPop(int pop) {
+ this.pop = pop;
+ }
}
diff --git a/src/main/java/nyc/c4q/json/ZipcodeDeserializer.java b/src/main/java/nyc/c4q/json/ZipcodeDeserializer.java
index a7a4c79..5114f79 100644
--- a/src/main/java/nyc/c4q/json/ZipcodeDeserializer.java
+++ b/src/main/java/nyc/c4q/json/ZipcodeDeserializer.java
@@ -1,8 +1,10 @@
package nyc.c4q.json;
+import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
@@ -10,6 +12,15 @@
public class ZipcodeDeserializer implements JsonDeserializer {
@Override
public Zipcode deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
- return null;
+
+ JsonObject jobject = (JsonObject) json;
+ JsonArray loc = jobject.get("loc").getAsJsonArray();
+ String _id = jobject.get("_id").getAsString();
+ String city = jobject.get("city").getAsString();
+ double[] location = {loc.get(0).getAsDouble(), loc.get(1).getAsDouble()};
+ String state = jobject.get("state").getAsString();
+ int pop = jobject.get("pop").getAsInt();
+
+ return new Zipcode(_id, city, location, pop, state);
}
}
diff --git a/src/main/res/layout/activity_listview.xml b/src/main/res/layout/activity_listview.xml
index 0d4b9d6..b0eac76 100644
--- a/src/main/res/layout/activity_listview.xml
+++ b/src/main/res/layout/activity_listview.xml
@@ -9,20 +9,30 @@
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="3"
+ android:text="You have not clicked anything." />
+
+
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="9"/>
\ No newline at end of file
diff --git a/src/main/res/layout/custom_list_item.xml b/src/main/res/layout/custom_list_item.xml
new file mode 100644
index 0000000..d1977bd
--- /dev/null
+++ b/src/main/res/layout/custom_list_item.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/nyc/c4q/Part2NetworkActivityTests.java b/src/test/java/nyc/c4q/Part2NetworkActivityTests.java
index 3a561c6..c1515d8 100644
--- a/src/test/java/nyc/c4q/Part2NetworkActivityTests.java
+++ b/src/test/java/nyc/c4q/Part2NetworkActivityTests.java
@@ -14,7 +14,6 @@
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.util.ActivityController;
import java.util.List;
@@ -54,7 +53,6 @@ public void test13NetworkActivityHTTPUrlConnectionGETOKHTTP() throws Exception {
Button httpbingetokhttp = (Button) Helpers.findViewByIdString(networkActivity, "httpbingetokhttp");
TextView httptextlog = (TextView) Helpers.findViewByIdString(networkActivity, "httptextlog");
httpbingetokhttp.callOnClick();
-
String replaced = urlParams.replaceAll("\\+"," ");
Assertions.assertThat(httptextlog).containsText(replaced);
}