O JSON (JavaScript Object Notation) nada mais é do que uma estrutura para representação dados em JavaScript.

A notação de objetos JavaScript (JSON) possui uma formatação bastante leve de troca de dados. Ela é fácil de ler e de escrever, para nós desenvolvedores e também é fácil de se implementar e de se gerar, para as máquinas. Essa notação de objetos está baseada em um subconjunto de linguagens de programação que são familiares às linguagens C, C++, C#, Java, JavaScript, Python e muitas outras.

Criando um novo Projeto

Para começarmos a desenvolver nossa aplicação, teremos que criar no Eclipse um novo projeto Android, que neste exemplo irá se chamar ConsumirJsonTwitter. Como vocês viram no nome do projeto, iremos consumir um JSON do top Trend do Twitter aqui no Brasil. Iremos acessar o JSON da seguinte página. Observem que no final da URL que iremos consumir, temos a terminação 23424768.json, esse número é o chamado woeid do Brasil.

Consumindo o Json

Bom pessoal, antes de começar, teremos que declarar no nosso AndroidManifest.xml a permissão de acesso à internet, se não a aplicação irá encerrar a cada vez que for solicitada uma conexão com a web. Para isso, abra o AndroidManifest.xml e deixe-o semelhante ao XML da listagem 1.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="devmedia.json"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".ConsumirJsonTwitterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
Listagem 1. Estrutura xml do arquivo AndroidManifest

A nossa aplicação terá apenas uma classe.java, pois assim que a aplicação for aberta, ela irá consumir de imediato o JSON do top Trend do Twitter e exibirá todo o conteúdo em uma lista. Ao escolher um objeto qualquer da lista, ele irá chamar o browser e exibirá o conteúdo referente aquele tópico escolhido anteriormente. Na então na classe principal iremos implementar todas as funções da nossa app.

Iremos agora implementar o nosso projeto. Observem na listagem 2, que logo no nosso método onCreate(), iremos chamar nossa AsyncTask(), com a URL do JSON. Isso significa que assim que abrirmos nossa app, iremos chamar em um nível de processamento paralelo o conteúdo dessa página. Caso não queiram utilizar AsyncTask, utilizem uma Thread, lembrando que no nosso caso o ideal é utilizar o AsyncTask.


package devmedia.json;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class ConsumirJsonTwitterActivity extends ListActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		new DownloadJsonAsyncTask()
				.execute("https://api.twitter.com/1/trends/23424768.json");
	}
Listagem 2. Chamando AsyncTask para download do JSON

Logo abaixo do nosso método onCreate(), iremos implementar um método chamado onListItemClick(), como mostra a listagem 3. Esse método será responsável por pegar o conteúdo especifico de uma posição específica na nossa lista. Como foi dito anteriormente, todo o conteúdo consumido no JSON será mostrado em uma lista, que será implementada posteriormente.


@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		
		Trend trend = (Trend)l.getAdapter().getItem(position);
		
		Intent it = new Intent(Intent.ACTION_VIEW, Uri.parse(trend.url));
		startActivity(it);
	}
Listagem 3. Método responsável pelo clique da lista

Agora iremos implementar nossa classe AsyncTask, essa é aquela responsável por realizar o download do JSON que nós chamamos anteriormente no nosso OnCreate(). Veja como vai ficar nossa AsyncTask, na listagem 4.


class DownloadJsonAsyncTask extends AsyncTask<String, Void, List<Trend>> {

ProgressDialog dialog;

@Override
protected void onPreExecute() {
	super.onPreExecute();
	dialog = ProgressDialog.show(ConsumirJsonTwitterActivity.this, "Aguarde",
			"Baixando JSON, Por Favor Aguarde...");
}
Listagem 4. AsyncTask, responsvel por baixar o JSON

Após termos concluído nosso AsyncTask, iremos implementar nossas listas. Elas irão receber as strings name e url, que são as especificações que temos lá no JSON, e são justamente essas strings que iremos mostrar na nossa aplicação. O nome será exibido na lista e a url será atribuída aos respectivos nomes das listas, lembrando que o JSON retorna uma lista de strings. Veja como será implementado nosso código na listagem 5.


@Override
protected List<Trend> doInBackground(String... params) {
	String urlString = params[0];

	HttpClient httpclient = new DefaultHttpClient();
	HttpGet httpget = new HttpGet(urlString);

	try {
		HttpResponse response = httpclient.execute(httpget);

		HttpEntity entity = response.getEntity();

		if (entity != null) {
			InputStream instream = entity.getContent();

			String json = toString(instream);
			instream.close();
			
			List<Trend> trends = getTrends(json);
			
			return trends;
		}
	} catch (Exception e) {
		Log.e("DEVMEDIA", "Falha ao acessar Web service", e);
	}
	return null;
}

private List<Trend> getTrends(String jsonString) {

	List<Trend> trends = new ArrayList<Trend>();
	
	try {
		JSONArray trendLists = new JSONArray(jsonString);
		JSONObject trendList = trendLists.getJSONObject(0);
		JSONArray trendsArray = trendList.getJSONArray("trends"); 

		JSONObject trend;
		
		for (int i = 0; i < trendsArray.length(); i++) {
			trend = new JSONObject(trendsArray.getString(i));

			Log.i("DEVMEDIA", "nome=" + trend.getString("name"));
			
			Trend objetoTrend = new Trend();
			objetoTrend.name = trend.getString("name");
			objetoTrend.url = trend.getString("url");
			
			trends.add(objetoTrend);
		}
	} catch (JSONException e) {
		Log.e("DEVMEDIA", "Erro no parsing do JSON", e);
	}

	return trends;
}
Listagem 5. Implementação da listagem do top Trend

Agora iremos criar o método onPostExeculte(), esse método será responsável por preencher nossa lista com os nomes que foram buscados pela AsyncTask. Logo abaixo desse método serão implementados todos os processos de serialização de dados, como será observado na listagem 6.


@Override
protected void onPostExecute(List<Trend> result) {
	super.onPostExecute(result);
	dialog.dismiss();
	if (result.size() > 0) {
		ArrayAdapter<Trend> adapter = new ArrayAdapter<Trend>(
				ConsumirJsonTwitterActivity.this,
				android.R.layout.simple_list_item_1, result);
		setListAdapter(adapter);

	} else {
		AlertDialog.Builder builder = new AlertDialog.Builder(
				ConsumirJsonTwitterActivity.this).setTitle("Atenção")
				.setMessage("Não foi possivel acessar essas informções...")
				.setPositiveButton("OK", null);
		builder.create().show();
	}
}

private String toString(InputStream is) throws IOException {

	byte[] bytes = new byte[1024];
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	int lidos;
	while ((lidos = is.read(bytes)) > 0) {
		baos.write(bytes, 0, lidos);
	}
	return new String(baos.toByteArray());
}
}

}

class Trend {
	String name;
	String url;
	
	@Override
	public String toString() {
		return name;
	}
}
Listagem 6. Método onPostExecute

Vejam na figura 1 como será nossa tela inicial, exibida após o dialog que foi implementado antes de exibir a listagem.

Lista com Top Trend do Twitter
Figura 1. Lista com Top Trend do Twitter

Conclusão

Bom pessoal, a lógica para se consumir outro JSON é a mesma, basta saber quais parâmetros você vai querer consumir. Isso pode ser verificado na própria página da web onde o JSON está disponível.

Com isso finalizamos mais um artigo, muito obrigado pela atenção de todos. Dúvidas/Sugestões comentem...