Acessando a rede através de HTTP

1423687551_Globe

Neste capítulo do curso de Android iremos aprender como acessar um servidor utilizando HTTP.

Iremos utilizar este servidor para fazer backup das notas criadas pela nossa aplicação QuickNotes.

Se você não estava acompanhando o Curso de Android, faça o download do projeto aqui, pois as alterações serão feitas neste projeto.

 

Clientes HTTP em Android

Em Android temos dois clientes HTTP:

  • Apache HTTP Client
  • HttpURLConnection

O Google aconselha o uso de HttpURLConnection desde a versão 2.3 (Gingerbread)

Usaremos o HTTPUrlConnection para enviar as notas, que no nosso exemplo são armazenadas no banco de dados local, para o servidor remoto. Abaixo segue a implementação:


String urlParameters = "nota=" + URLEncoder.encode(note,"UTF-8");
String request = "http://tests.felipesilveira.com.br/android-core/insert.php";
URL url = new URL(request);

// Criando a instância de HttpURLConnection responsável por acessar a rede
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setInstanceFollowRedirects(false);
// Vamos enviar a requisição via POST
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("charset", "utf-8");
connection.setRequestProperty("Content-Length", "" +
		Integer.toString(urlParameters.getBytes().length));
connection.setUseCaches (false);

// Criando um DataOutputStream que será usado para receber a resposta do servidor.
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();

String response = "";
Scanner inStream = new Scanner(connection.getInputStream());

while (inStream.hasNextLine()) {
	response += (inStream.nextLine());
}

// Removendo possiveis quebras de linha
response.replaceAll("\n", "");
Log.v("DataSync", "Resposta do server=("+response+")");

inStream.close();
connection.disconnect();

Para fazer a sincronização com nosso servidor remoto na aplicação QuickNotes, vamos seguir dois passos:

  1. Criar uma flag no banco de dados, para termos controle do que já foi enviado.
  2. Usar HTTPUrlConnection para enviar os dados via POST para o servido.

Passo 1 – Controle de sincronização

Para criar uma coluna extra na tabela do nosso banco de dados, basta alterar o método onCreate da classe QuickNotesProvider$DBHelper


@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + NOTES_TABLE + " (" +
Notes.NOTE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
Notes.SYNCED + " INTEGER," +
Notes.TEXT + " LONGTEXT" + ");");

Após a alteração no DBHelper, é necessário criar a constante SYNCED na classe QuickNotesProvider$Notes, que fica assim


public static final class Notes implements  BaseColumns {
	public static final Uri CONTENT_URI = Uri.parse("content://"
				+ QuickNotesProvider.AUTHORITY + "/notes");

	public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.quicknotes";
	public static final String NOTE_ID = "_id";
	public static final String TEXT = "text";
	public static final String SYNCED = "synced";
}

Assim, a nossa classe QuickNotesProvider deve ficar assim:


package android.helloworld;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.Context;
import android.content.UriMatcher;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;

public class QuickNotesProvider extends ContentProvider {

	// Authority do nosso provider, a ser usado nas Uris.
	public static final String AUTHORITY = "android.helloworld.quicknotesprovider";

	// Nome do arquivo que ira conter o banco de dados.
	private static  final String DATABASE_NAME = "quicknotes.db";

	// Versao do banco de dados.
	// Este valor eh importante pois sera usado em futuros updates do DB.
	private static  final int  DATABASE_VERSION = 1;

	// Nome da tabela que ira conter as anotacoes.
	private static final  String NOTES_TABLE = "notes";

	// 'Id' da Uri referente as notas do usuario.
	private  static final int NOTES = 1;

	// Tag usada para imprimir os logs.
	public static final String TAG = "QuickNotesProvider";

	// Instancia da classe utilitaria
	private DBHelper mHelper;

	// Uri matcher - usado para extrair informacoes das Uris
    private static final UriMatcher mMatcher;

    private static HashMap<String, String> mProjection;

    static {
		mProjection = new HashMap<String, String>();
		mProjection.put(Notes.NOTE_ID, Notes.NOTE_ID);
		mProjection.put(Notes.TEXT, Notes.TEXT);
    }

    static {
    	mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		mMatcher.addURI(AUTHORITY, NOTES_TABLE, NOTES);
    }

	/////////////////////////////////////////////////////////////////
	//           Metodos overrided de ContentProvider              //
	/////////////////////////////////////////////////////////////////
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = mHelper.getWritableDatabase();
        int count;
        switch (mMatcher.match(uri)) {
        	case NOTES:
                count = db.delete(NOTES_TABLE, selection, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("URI desconhecida " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
	}

	@Override
	public String getType(Uri uri) {
	        switch (mMatcher.match(uri)) {
	            case NOTES:
	                return Notes.CONTENT_TYPE;
	            default:
	                throw new IllegalArgumentException("URI desconhecida " + uri);
	        }
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		Log.i(TAG, "insert op");
        switch (mMatcher.match(uri)) {
	    	case NOTES:
		        SQLiteDatabase db = mHelper.getWritableDatabase();
		        long rowId = db.insert(NOTES_TABLE, Notes.TEXT, values);
		        if (rowId > 0) {
		            Uri noteUri = ContentUris.withAppendedId(Notes.CONTENT_URI, rowId);
		            getContext().getContentResolver().notifyChange(noteUri, null);
		            return noteUri;
		        }
	        default:
	            throw new IllegalArgumentException("URI desconhecida " + uri);
        }
	}

	@Override
	public boolean onCreate() {
		mHelper = new DBHelper(getContext());;
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
			// Aqui usaremos o SQLiteQueryBuilder para construir
			// a query que sera feito ao DB, retornando um cursor
			// que enviaremos a aplicacao.
	        SQLiteQueryBuilder builder = new  SQLiteQueryBuilder();
	        SQLiteDatabase database = mHelper.getReadableDatabase();
	        Cursor cursor;
	        switch (mMatcher.match(uri)) {
	            case NOTES:
	            	// O Builer recebera dois parametros: a tabela
	            	// onde sera feita a busca, e uma projection -
	            	// que nada mais eh que uma HashMap com os campos
	            	// que queremos recuperar do banco de dados.
	                builder.setTables(NOTES_TABLE);
	                builder.setProjectionMap(mProjection);
	                break;

	            default:
	                throw new IllegalArgumentException("URI desconhecida " + uri);
	        }

	        cursor = builder.query(database, projection, selection,
	        		                 selectionArgs, null, null, sortOrder);

	        cursor.setNotificationUri(getContext().getContentResolver(), uri);
	        return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
	        SQLiteDatabase db = mHelper.getWritableDatabase();
	        int count;
	        switch (mMatcher.match(uri)) {
	            case NOTES:
	                count = db.update(NOTES_TABLE, values, selection, selectionArgs);
	                break;
	            default:
	                throw new IllegalArgumentException("URI desconhecida " + uri);
	        }

	        getContext().getContentResolver().notifyChange(uri, null);
	        return count;
	}

	/////////////////////////////////////////////////////////////////
	//                Inner Classes utilitarias                    //
	/////////////////////////////////////////////////////////////////
    public static final class Notes implements  BaseColumns {
        public static final Uri CONTENT_URI = Uri.parse("content://"
	                + QuickNotesProvider.AUTHORITY + "/notes");

        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.quicknotes";
        public static final String NOTE_ID = "_id";
        public static final String TEXT = "text";
        public static final String SYNCED = "synced";
    }

    private static class DBHelper extends SQLiteOpenHelper {

        DBHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        /* O metodo onCreate eh chamado quando o provider eh executado pela
         * primeira vez, e usado para criar as tabelas no database
         */
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE " + NOTES_TABLE + " (" +
            		Notes.NOTE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
            		Notes.SYNCED + " INTEGER," +
            		Notes.TEXT + " LONGTEXT" + ");");
        }

        /* O metodo onUpdate eh invocado quando a versao do banco de dados
         * muda. Assim, eh usado para fazer adequacoes para a aplicacao
         * funcionar corretamente.
         */
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        	// Como ainda estamos na primeira versao do DB,
        	// nao precisamos nos preocupar com o update agora.
        }
    }
}

Além das alterações no Content Provider, precisamos alterar o método doInBackground da AsyncTask na MainActivity para passar a gravar as notas com a flag SYNCED = 0, significando que ela ainda não foi enviada ao servidor.

         protected Uri doInBackground(String... string) {
            ContentValues values = new ContentValues();
            values.put(QuickNotesProvider.Notes.TEXT, string[0]);
            // Gravando a flag SYNCED com o valor 0, significando que
            // a nota ainda não foi enviada ao servidor
            values.put(QuickNotesProvider.Notes.SYNCED, "0");

            return getContentResolver().insert(
                    QuickNotesProvider.Notes.CONTENT_URI, values);
         }

Passo 2 – Sincronização com o servidor remoto

Com a flag criada, seguimos ao segundo passo que é a criação dos métodos para acesso ao servidor remoto.

Criaremos para isso a class DataSync, que possui dois métodos:

  • syncPendingNotes(), responsável por procurar no banco de dados as notas ainda não enviadas, e
  • sendPendingNote(), responsável por enviar uma nota ao servidor.

Com a implementação destes métodos, a classe DataSync fica assim:

package android.helloworld;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.helloworld.QuickNotesProvider;
import android.net.Uri;
import android.util.Log;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class DataSync {

	private static final String TAG = "DataSync";

	private Context mContext;

	public DataSync(Context context) {
		mContext = context;
	}

	public void syncPendingNotes() {
		Log.v(TAG, "Iniciando sincronizacao");
		// Procurando no banco de dados as entradas com SYNCED = 0,
		// o que significa que tal dado ainda nao foi enviado ao
		// servidor remoto.
		String columns[] = new String[] {
				QuickNotesProvider.Notes.TEXT,
				QuickNotesProvider.Notes.NOTE_ID};
		Uri contentUri = QuickNotesProvider.Notes.CONTENT_URI;
		Cursor cur = mContext.getContentResolver().query(contentUri, columns,
				QuickNotesProvider.Notes.SYNCED + "=0",
				null,
				null
				);
		if (cur.moveToFirst()) {
			Log.v("DataSync", "Existem notas a serem enviadas.");
			String note = null;
			int id = 0;
			do {
				// Obtendo o valor do campo text
				note = cur.getString(
						cur.getColumnIndex(QuickNotesProvider.Notes.TEXT));
				id = cur.getInt(
						cur.getColumnIndex(QuickNotesProvider.Notes.NOTE_ID));

				Log.v("DataSync", "Sincronizando " + note );
				if(sendPendingNote(note)) {
					Log.v("DataSync", "Sincronizacao feita com sucesso!");
					// Como a sincronizacao foi bem sucedida, vamos agora marcar a
					// flag SYNCED com 1.
					ContentValues values = new ContentValues();
					values.put(QuickNotesProvider.Notes.SYNCED, "1");
					mContext.getContentResolver().update(contentUri,
							values,
							QuickNotesProvider.Notes.NOTE_ID + "=" + id,
							null);
				}

			} while (cur.moveToNext());
		} else {
			Log.v(TAG, "Sem novas notas");
		}
		cur.close();
	}

	public boolean sendPendingNote(String note) {
		try {
			String urlParameters = "nota=" + URLEncoder.encode(note,"UTF-8");
			String request = "http://tests.felipesilveira.com.br/android-core/insert.php";
			URL url = new URL(request);

			// Criando a instância de HttpURLConnection responsável por acessar a rede
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setInstanceFollowRedirects(false);
			// Vamos enviar a requisição via POST
			connection.setRequestMethod("POST");
			connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			connection.setRequestProperty("charset", "utf-8");
			connection.setRequestProperty("Content-Length", "" +
					Integer.toString(urlParameters.getBytes().length));
			connection.setUseCaches (false);

			// Criando um DataOutputStream que será usado para receber a resposta do servidor.
			DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
			wr.writeBytes(urlParameters);
			wr.flush();
			wr.close();

			String response = "";
			Scanner inStream = new Scanner(connection.getInputStream());

			while (inStream.hasNextLine()) {
				response += (inStream.nextLine());
			}

			// Removendo possiveis quebras de linha
			response.replaceAll("\n", "");
			Log.v("DataSync", "Resposta do server=("+response+")");

			inStream.close();
			connection.disconnect();

			// Quando a nota eh corretamente salva no servidor,
			// este responde com "1".
			return response.equals("1");

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 

		return false;
	}
}

 

Iniciando a sincronização

Por fim, basta invocar a sincronização no método doInBackground() da AsyncTask que criamos na MainActivity. Porém, só chamaremos o método se houver conectividade com internet – para saber isso basta usar o ConnectivityManager:


ConnectivityManager cm =
		(ConnectivityManager)getSystemService(
				Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if((activeNetwork != null) && activeNetwork.isConnected()) {
	DataSync sync = new DataSync(MainActivity.this);
	sync.syncPendingNotes();
}

Integrando o código na MainActivity:


package android.helloworld;

import android.app.ListActivity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class MainActivity extends ListActivity {

	private static final String TAG = "QuickNotesMainActivity";
	private Cursor mCursor;

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

		Log.d(TAG, "Criando a MainActivity");

		setContentView(R.layout.main);

		Intent i = new Intent(this, WelcomeActivity.class);
		startActivity(i);

		Button insertButton = (Button)findViewById(R.id.insert_button);
		insertButton.setOnClickListener(mInsertListener);

		// adicionando um 'Hint' ao Editbox.
		EditText editBox = (EditText)findViewById(R.id.edit_box);
		editBox.setHint("Nova nota...");

		mCursor = this.getContentResolver().
				query(QuickNotesProvider.Notes.CONTENT_URI, null, null, null, null);

		ListAdapter adapter = new SimpleCursorAdapter(
				// O primeiro parametro é o context.
				this,
				// O segundo, o layout de cada item.
				R.layout.list_item,
				// O terceiro parametro eh o cursor que contem os dados
				// a serem mostrados
				mCursor,
				// o quarto parametro eh um array com as colunas do cursor
				// que serao mostradas
				new String[] {QuickNotesProvider.Notes.TEXT},
				// o quinto parametro é um array (com o mesmo tamanho
				// do anterior) com os elementos que receberao
				// os dados.
				new int[] {R.id.text});

		setListAdapter(adapter);
	}

	/*
	 *  Definindo um OnClickListener para o botão "Inserir"
	 */
	private OnClickListener mInsertListener = new OnClickListener() {
		public void onClick(View v) {
			EditText editBox = (EditText)findViewById(R.id.edit_box);
			addNote(editBox.getText().toString());
			editBox.setText("");
		}
	};

	/*
	 * Método responsável por inserir um registro no content provider
	 */
	protected void addNote(String text) {
		AddNoteTask task = new AddNoteTask();
		// É necessário passar como parâmetro um array de strings,
		// que será o parâmetro recebido pelo método doInBackground.
		// Neste caso, será passado um array com apenas um item: A nova nota
		task.execute(new String[] { text } );
	}

	private class AddNoteTask extends AsyncTask<String, Void, Uri> {
		@Override
		protected Uri doInBackground(String... string) {
			ContentValues values = new ContentValues();
			values.put(QuickNotesProvider.Notes.TEXT, string[0]);
			// Gravando a flag SYNCED com o valor 0, significando que
			// a nota ainda não foi enviada ao servidor
			values.put(QuickNotesProvider.Notes.SYNCED, "0");

			Uri inserted = getContentResolver().insert(
					QuickNotesProvider.Notes.CONTENT_URI, values);

			ConnectivityManager cm =
					(ConnectivityManager)getSystemService(
							Context.CONNECTIVITY_SERVICE);
			NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
			if((activeNetwork != null) && activeNetwork.isConnected()) {
				DataSync sync = new DataSync(MainActivity.this);
				sync.syncPendingNotes();
			}

			return inserted;

		}

		@Override
		protected void onPostExecute(Uri result) {
			// Após a inserção da nota, vamos mostrar um Toast ao usuário
			Toast toast = Toast.makeText(MainActivity.this,
					"Nota inserida com sucesso!",
					Toast.LENGTH_SHORT);
			toast.show();
		}
	}
}

Backend

Para os testes, foi criado um backend no seguinte endereço:
http://tests.felipesilveira.com.br/android-core/

Você pode conferir se a sua nota foi corretamente enviada através do endereço:

http://tests.felipesilveira.com.br/android-core/insert.php

Desenvolvendo para Android

9 respostas to “Acessando a rede através de HTTP”

  1. Franklin disse:

    Felipe, primeiramente queria dizer que gostei muito e estou aprendendo muito com esses seus posts. Mas tenho uma duvida, no método doInBackground ele pede um retorno, como posso resolver isso?

  2. Olá Franklin!

    Obrigado pelo comentário! Estava faltando uma linha no exemplo, agora já está corrigido.

  3. ilton barbosa disse:

    Oi Felipe,
    Parabens pela iniciativa.
    Quanto à conexão com banco de dados, é comum utilizar o SQL lite em aplicações mobile? ou só utilizou aqui para facilitar o ensinamento?

  4. Jefferson disse:

    Olá Felipe!

    Primeiramente, parabéns por este magnífico trabalho e boa vontade em compartilhar seu conhecimento.

    Me deparei com um erro nesta fase do projeto, nada complicado, mas fica como dica caso alguém tenha este mesmo problema.

    Ao tentar inserir uma nota, a aplicação fechou, com o seguinte erro no LogCat:
    “java.lang.SecurityException: ConnectivityService: Neither user nor current process has android.permission.ACCESS_NETWORK_STATE.”

    Uma rápida pesquisada, consegui solucionar o problema, adicionando as permissões abaixo ao AndroidManifest.xml:

    Grande abraço,

    Jefferson

  5. Jefferson disse:

    Permissões(Trocar os ? por tag):

    ?uses-permission android:name=”android.permission.INTERNET” /?
    ?uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” /?
    ?uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE”/?

  6. albert carloe disse:

    Gostaria de saber quanto voce cobraria para desenvolver um plugin cordova/phonegap para android para a impressora termica p25 bluebamboo. Existe um demo neste link gostaria de transformalo em um plugin https://github.com/lorensiuswlt/P25Demo

  7. Emerson disse:

    Olá Felipe,

    Tenho empresa de rastreamento veicular, temos um app ativo somente de posição dos veiculos…

    gostaria de criar algo para interagir o app com meu sistema tanto pra comandos quanto a envio e recebimento de mensagem em texto livre…

    Faz esse tipo de projeto?

    Abraço

    Whats 19-974025947

  8. Johnatan Cunha disse:

    Olá Felipe, quero te parabenizar pela iniciativa.Apesar de não estar tratado aqui por ser fora do tópico Android, mas gostaria de saber como foi feito o backend para tratar a sincronização das mensagens. Tem algum tutorial que posso seguir para fazê-lo?

  9. Luiz Felipe D Silva disse:

    Olá bom dia, eu fiz de uma outra maneira, mas não esta dando certo. estou enviando o código onde faço a conexão com o banco e salvo as informações, se vc puder dar uma olhada eu agradeço…
    package gp_adm_ti_pc.example.com.grandpneus.Uteis;

    import android.net.Uri;
    import android.os.AsyncTask;

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.HttpURLConnection;
    import java.net.URL;

    public class AtualizaDadosClienteSite extends AsyncTask {
    private String nome;
    private String cpf;
    private String telefone;
    private String cidade;

    public void setNome(String nome) {
    this.nome = nome;
    }

    public void setCpf(String cpf) {
    this.cpf = cpf;
    }

    public void setTelefone(String telefone) {
    this.telefone = telefone;
    }

    public void setCidade(String cidade) {
    this.cidade = cidade;
    }

    public String getNome() {
    return nome;
    }

    public String getCpf() {
    return cpf;
    }

    public String getTelefone() {
    return telefone;
    }

    public String getCidade() {
    return cidade;
    }

    @Override
    protected String doInBackground(Void… params) {
    HttpURLConnection urlConnection = null;

    try{
    URL url = new URL(“http://www.grandpneus.com.br/www.apk_php.SalvaCliente.php”);
    urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setReadTimeout(10000);
    urlConnection.setConnectTimeout(15000);
    urlConnection.setRequestMethod(“POST”);
    urlConnection.setDoInput(true);
    urlConnection.setDoOutput(true);

    Uri.Builder builder = new Uri.Builder();
    builder.appendQueryParameter(“CPF”, getCpf());
    builder.appendQueryParameter(“NOME”, getNome());
    builder.appendQueryParameter(“TELEFONE”, getTelefone());
    builder.appendQueryParameter(“CIDADE”, getCidade());
    String query = builder.build().getEncodedQuery();

    OutputStream os = urlConnection.getOutputStream();
    BufferedWriter writer = new BufferedWriter(
    new OutputStreamWriter(os, “UTF-8”));
    writer.write(query);
    writer.flush();
    writer.close();
    os.close();

    //String result = readStream(urlConnection.getInputStream());

    urlConnection.connect();
    }
    catch (Exception erro){
    erro.printStackTrace();

    if (urlConnection != null) {
    urlConnection.disconnect();
    }
    }
    return null;
    }

    public static String readStream(InputStream in) {
    BufferedReader reader = null;
    StringBuilder builder = new StringBuilder();
    try {
    reader = new BufferedReader(new InputStreamReader(in));
    String line = null;
    while ((line = reader.readLine()) != null) {
    builder.append(line + “\n”);
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    if (reader != null) {
    try {
    reader.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    return builder.toString();
    }
    }

Deixe um comentário