Wednesday 28 March 2012

Google Weather App

Last exercise demonstrate the basic of Google Weather API. It's modified to be a completed app with better look, with function of searching place.

Google Weather App

Main Java code:

package com.exercise.AndroidGoogleWeather;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidGoogleWeatherActivity extends Activity {

class ForecastInformation{
String city;
String postal_code;
String forecast_date;
String current_date_time;
String unit_system;
}

class CurrentConditions{
String condition;
String temp_f;
String temp_c;
String humidity;
String icon;
String wind_condition;
}

class ForecastConditions{
String day_of_week;
String low;
String high;
String icon;
String condition;
}

ForecastInformation forecastInformation;
CurrentConditions currentConditions;
List<ForecastConditions> forecastConditionsList;

Button buttonEnter;
EditText edittextPlace;
ImageView iconCurrent;
TextView textCurrent;
TextView textInfo;
ListView listForcast;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

buttonEnter = (Button)findViewById(R.id.enter);
edittextPlace = (EditText)findViewById(R.id.place);
iconCurrent = (ImageView)findViewById(R.id.iconcurrent);
textCurrent = (TextView)findViewById(R.id.textcurrent);
textInfo = (TextView)findViewById(R.id.textinfo);
listForcast = (ListView)findViewById(R.id.listforcast);

buttonEnter.setOnClickListener(EnterOnClickListener);

}

Button.OnClickListener EnterOnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
String place = edittextPlace.getText().toString();

String weatherString = QueryGoogleWeather(place);
Document weatherDoc = convertStringToDocument(weatherString);

if(parseGoogleWeather(weatherDoc)){
//Display Result
String c = currentConditions.condition + "\n"
+ currentConditions.temp_f + "f\n"
+ currentConditions.temp_c + "c\n"
+ currentConditions.humidity + "\n"
+ currentConditions.wind_condition + "\n";

textCurrent.setText(c);
Bitmap bm = LoadIcon(currentConditions.icon);
iconCurrent.setImageBitmap(bm);

textInfo.setText("city: " + forecastInformation.city + "\n"
+ "postal code: " + forecastInformation.postal_code + "\n"
+ "forecast date: " + forecastInformation.forecast_date + "\n"
+ "current date time: " + forecastInformation.current_date_time + "\n"
+ "unit: " + forecastInformation.unit_system);

listForcast.setAdapter(new MyCustomAdapter(
AndroidGoogleWeatherActivity.this,
R.layout.row,
forecastConditionsList));
}


}

};

public class MyCustomAdapter extends ArrayAdapter<ForecastConditions> {

public MyCustomAdapter(Context context, int textViewResourceId,
List<ForecastConditions> objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.row, parent, false);
ImageView iconForecast = (ImageView)row.findViewById(R.id.iforecast);
TextView textForecast = (TextView)row.findViewById(R.id.tforecast);


textForecast.setText(
forecastConditionsList.get(position).day_of_week + "\n"
+ " - " + forecastConditionsList.get(position).condition + "\n"
+ forecastConditionsList.get(position).low + " ~ "
+ forecastConditionsList.get(position).high);

Bitmap bm = LoadIcon(forecastConditionsList.get(position).icon);
iconForecast.setImageBitmap(bm);

return row;
}

}

private Bitmap LoadIcon(String iconURL)
{
BitmapFactory.Options bmOptions;
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
String image_URL = "http://www.google.com" + iconURL;

Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(image_URL);
bitmap = BitmapFactory.decodeStream(in, null, bmOptions);
in.close();
} catch (IOException e1) {
}
return bitmap;
}

private InputStream OpenHttpConnection(String strURL) throws IOException{
InputStream inputStream = null;
URL url = new URL(strURL);
URLConnection conn = url.openConnection();

try{
HttpURLConnection httpConn = (HttpURLConnection)conn;
httpConn.setRequestMethod("GET");
httpConn.connect();

if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
inputStream = httpConn.getInputStream();
}
}catch (Exception ex){
}
return inputStream;
}

private boolean parseGoogleWeather(Document srcDoc){

boolean result = false;

forecastInformation = new ForecastInformation();
currentConditions = new CurrentConditions();

//-- Get forecast_information
NodeList forecast_information = srcDoc.getElementsByTagName("forecast_information");
if (forecast_information.getLength() > 0){

//Assume place found if "forecast_information" exist
result = true;

NodeList infoChilds = forecast_information.item(0).getChildNodes();

for(int i=0; i<infoChilds.getLength(); i++){
Node n = infoChilds.item(i);

String nName = n.getNodeName();
String nValue
= n.getAttributes().getNamedItem("data").getNodeValue().toString();
if (nName.equalsIgnoreCase("city")){
forecastInformation.city = nValue;
}else if((nName.equalsIgnoreCase("postal_code"))){
forecastInformation.postal_code = nValue;
}else if((nName.equalsIgnoreCase("forecast_date"))){
forecastInformation.forecast_date = nValue;
}else if((nName.equalsIgnoreCase("current_date_time"))){
forecastInformation.current_date_time = nValue;
}else if((nName.equalsIgnoreCase("unit_system"))){
forecastInformation.unit_system = nValue;
}
}
}

//-- Get current_conditions
NodeList current_conditions = srcDoc.getElementsByTagName("current_conditions");
if(current_conditions.getLength()>0){
NodeList currentChilds = current_conditions.item(0).getChildNodes();

for(int i=0; i<currentChilds.getLength(); i++){
Node n = currentChilds.item(i);

String nName = n.getNodeName();
String nValue
= n.getAttributes().getNamedItem("data").getNodeValue().toString();
if (nName.equalsIgnoreCase("condition")){
currentConditions.condition = nValue;
}else if((nName.equalsIgnoreCase("temp_f"))){
currentConditions.temp_f = nValue;
}else if((nName.equalsIgnoreCase("temp_c"))){
currentConditions.temp_c = nValue;
}else if((nName.equalsIgnoreCase("humidity"))){
currentConditions.humidity = nValue;
}else if((nName.equalsIgnoreCase("icon"))){
currentConditions.icon = nValue;
}else if((nName.equalsIgnoreCase("wind_condition"))){
currentConditions.wind_condition = nValue;
}
}
}

//-- Get forecast_conditions
NodeList forecast_conditions = srcDoc.getElementsByTagName("forecast_conditions");
if (forecast_conditions.getLength()>0){
int forecast_conditions_length = forecast_conditions.getLength();

forecastConditionsList = new ArrayList<ForecastConditions>();

for(int j=0; j<forecast_conditions_length; j++){

ForecastConditions tmpForecastConditions = new ForecastConditions();

NodeList forecasrChilds = forecast_conditions.item(j).getChildNodes();

for(int i=0; i<forecasrChilds.getLength(); i++){

Node n = forecasrChilds.item(i);

String nName = n.getNodeName();
String nValue
= n.getAttributes().getNamedItem("data").getNodeValue().toString();

if (nName.equalsIgnoreCase("condition")){
tmpForecastConditions.condition = nValue;
}else if((nName.equalsIgnoreCase("day_of_week"))){
tmpForecastConditions.day_of_week = nValue;
}else if((nName.equalsIgnoreCase("low"))){
tmpForecastConditions.low = nValue;
}else if((nName.equalsIgnoreCase("high"))){
tmpForecastConditions.high = nValue;
}else if((nName.equalsIgnoreCase("icon"))){
tmpForecastConditions.icon = nValue;
}
}
forecastConditionsList.add(tmpForecastConditions);
}
}

return result;
}

private Document convertStringToDocument(String src){
Document dest = null;

DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser;

try {
parser = dbFactory.newDocumentBuilder();
dest = parser.parse(new ByteArrayInputStream(src.getBytes()));
} catch (ParserConfigurationException e1) {
e1.printStackTrace();
Toast.makeText(AndroidGoogleWeatherActivity.this,
e1.toString(), Toast.LENGTH_LONG).show();
} catch (SAXException e) {
e.printStackTrace();
Toast.makeText(AndroidGoogleWeatherActivity.this,
e.toString(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(AndroidGoogleWeatherActivity.this,
e.toString(), Toast.LENGTH_LONG).show();
}

return dest;
}

private String QueryGoogleWeather(String p){

String uriPlace = Uri.encode(p);

String qResult = "";
String queryString = "http://www.google.com/ig/api?hl=en&weather=" + uriPlace;

HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(queryString);

try {
HttpEntity httpEntity = httpClient.execute(httpGet).getEntity();

if (httpEntity != null){
InputStream inputStream = httpEntity.getContent();
Reader in = new InputStreamReader(inputStream);
BufferedReader bufferedreader = new BufferedReader(in);
StringBuilder stringBuilder = new StringBuilder();

String stringReadLine = null;

while ((stringReadLine = bufferedreader.readLine()) != null) {
stringBuilder.append(stringReadLine + "\n");
}

qResult = stringBuilder.toString();
}

} catch (ClientProtocolException e) {
e.printStackTrace();
Toast.makeText(AndroidGoogleWeatherActivity.this,
e.toString(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(AndroidGoogleWeatherActivity.this,
e.toString(), Toast.LENGTH_LONG).show();
}

return qResult;
}
}


main.xml layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/enter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="- Enter -"/>
<EditText
android:id="@+id/place"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<ImageView
android:id="@+id/iconcurrent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
<TextView
android:id="@+id/textcurrent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:gravity="center"/>

</LinearLayout>
<TextView
android:id="@+id/textinfo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<ListView
android:id="@+id/listforcast"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
</LinearLayout>


row.xml, the row layout of the custom ListView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/iforecast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp" />
<TextView
android:id="@+id/tforecast"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>


You have to modify AndroidManifest.xml to grand permission of "android.permission.INTERNET"

Download the files.

Borneo08

About Borneo08

Author Description here.. Nulla sagittis convallis. Curabitur consequat. Quisque metus enim, venenatis fermentum, mollis in, porta et, nibh. Duis vulputate elit in elit. Mauris dictum libero id justo.

Subscribe to this Blog via Email :

More links

Related Posts Plugin for WordPress, Blogger...