Pergunta

I'm trying to make an application which needs to connect to a local server to extract data ! when there is a connection , the application is working fine ! but when the connection is down the application wait about 15 seconds and then crash !! i have seen all possible solution in internet ! but no one worked for me ! Please need a hand to solve this problem here is the source code !

package com.example.chap6_5;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.UnresolvedAddressException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    EditText Username, Password;
    TextView Error_Login;
    Button Button_Login;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Username = (EditText) findViewById(R.id.username);
        Password = (EditText) findViewById(R.id.password);
        Error_Login = (TextView)findViewById(R.id.ErrorLogin);
        Button_Login = (Button)findViewById(R.id.login);

        Button_Login.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                new DownloadTextTask().execute("http://192.168.1.100/PHP_MVC/mobile/MLogin.php");

            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    // ---Connects using HTTP POST---
    public InputStream OpenHttpPOSTConnection(String url) {
        InputStream inputStream = null;
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);


            // ---the key/value pairs to post to the server---
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("username", Username.getText().toString()
                    .toString()));
            nameValuePairs.add(new BasicNameValuePair("password", Password.getText().toString()));
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse httpResponse = httpclient.execute(httpPost);
            inputStream = httpResponse.getEntity().getContent();
        }
         catch (ConnectTimeoutException  e)
         {
             Log.d("OpenHttpPOSTConnection TIMEOUT", e.getLocalizedMessage());
         }
        catch (Exception e) {
            Log.d("OpenHttpPOSTConnection", e.getLocalizedMessage());
        }
        return inputStream;
    }

    private String DownloadText(String URL) {
        int BUFFER_SIZE = 2000;
        InputStream in = null;
        try {
            in = OpenHttpPOSTConnection(URL);

        } 

        catch (Exception e) {
            Log.d("Networking", e.getLocalizedMessage());
            return "";
        }
        InputStreamReader isr = new InputStreamReader(in);
        int charRead;
        String str = "";
        char[] inputBuffer = new char[BUFFER_SIZE];
        try {
            while ((charRead = isr.read(inputBuffer)) > 0) {
                // ---convert the chars to a String---
                String readString = String
                        .copyValueOf(inputBuffer, 0, charRead);
                str += readString;
                inputBuffer = new char[BUFFER_SIZE];
            }
            in.close();
        } catch (IOException e) {
            Log.d("DownloadText", e.getLocalizedMessage());
            return "";
        }
        return str;
    }

    private class DownloadTextTask extends AsyncTask<String, Void, String> {
        protected String doInBackground(String... urls) {
            return DownloadText(urls[0]);
        }

        @Override
        protected void onPostExecute(String result) {
            try {

                JSONObject jsonObject = new JSONObject(result);
                String success = jsonObject.getString("Success");
                Toast.makeText(getBaseContext(), success, Toast.LENGTH_LONG).show();
                if (Integer.parseInt(success)==1)
                {
                    Log.d("DownloadTextTask", "success");
                    Intent i_Dashboard = new Intent(getApplicationContext(),Dashboard.class);
                    startActivity(i_Dashboard);
                    finish();
                }
                else
                {
                    Error_Login.setText("Error Login : Username/password are wrong !");
                }
                Log.d("DownloadTextTask", result);

            } catch (Exception e) {
                Log.d("DownloadText", e.getLocalizedMessage());
            }

        }
    }
}

[EDITED] the new OnCreate Method

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Username = (EditText) findViewById(R.id.username);
        Password = (EditText) findViewById(R.id.password);
        Error_Login = (TextView)findViewById(R.id.ErrorLogin);
        Button_Login = (Button)findViewById(R.id.login);

        Button_Login.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                ConnectionDetector conn = new ConnectionDetector(getApplicationContext());
                 if(conn.isConnectingToInternet())
                 {
                     Toast.makeText(getApplicationContext(), "CONNECTEDs", Toast.LENGTH_LONG).show();
                new DownloadTextTask().execute("http://192.168.1.100/PHP_MVC/mobile/MLogin.php");
                 }
                 else
                     Toast.makeText(getApplicationContext(), "No connection", Toast.LENGTH_LONG).show();

            }
        });

    }

here is the logcat :

05-01 06:08:07.673: D/OpenGLRenderer(1276): TextureCache::get: create texture(0xb881bb38): name, size, mSize = 13, 7488, 1106852
05-01 06:08:10.773: D/OpenHttpPOSTConnection TIMEOUT(1276): Connect to /192.168.1.100:80 timed out
05-01 06:08:10.773: W/dalvikvm(1276): threadid=10: thread exiting with uncaught exception (group=0xa62b0288)
05-01 06:08:10.773: E/AndroidRuntime(1276): FATAL EXCEPTION: AsyncTask #1
05-01 06:08:10.773: E/AndroidRuntime(1276): java.lang.RuntimeException: An error occured while executing doInBackground()
05-01 06:08:10.773: E/AndroidRuntime(1276):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.lang.Thread.run(Thread.java:856)
05-01 06:08:10.773: E/AndroidRuntime(1276): Caused by: java.lang.NullPointerException
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.io.Reader.<init>(Reader.java:64)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.io.InputStreamReader.<init>(InputStreamReader.java:122)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.io.InputStreamReader.<init>(InputStreamReader.java:59)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at com.example.chap6_5.MainActivity.DownloadText(MainActivity.java:118)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at com.example.chap6_5.MainActivity.access$0(MainActivity.java:106)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at com.example.chap6_5.MainActivity$DownloadTextTask.doInBackground(MainActivity.java:140)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at com.example.chap6_5.MainActivity$DownloadTextTask.doInBackground(MainActivity.java:1)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-01 06:08:10.773: E/AndroidRuntime(1276):     ... 5 more
05-01 06:08:10.893: D/OpenGLRenderer(1276): TextureCache::get: create texture(0xb87ab998): name, size, mSize = 24, 7488, 1114340
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::flush: target size: 668604
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 2, 5184, 1109156
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 4, 20736, 1088420
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 10, 2304, 1086116
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 13, 7488, 1078628
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 6, 7488, 1071140
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 1, 1048576, 22564

Thanks so much!

Foi útil?

Solução

First Method

in your OpenHttpPOSTConnection function, check for the status of the Internet

...
HttpResponse httpResponse = httpclient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode() == 200) //which means there is connection
     inputStream = httpResponse.getEntity().getContent();
else
     return null;

then check if null get out of the AsyncTask.. by maybe providing the onPostExcute and null value, and depend of null show a toast to tell the user there is no Internet connection.

Second Method

also you can have a ConnectionDetector class where you check if there is an Internet connection prior to execute of AsyncTask..

public class ConnectionDetector {

private Context _context;

public ConnectionDetector(Context context){
    this._context = context;
}

public boolean isConnectingToInternet(){
    ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
      if (connectivity != null) 
      {
          NetworkInfo[] info = connectivity.getAllNetworkInfo();
          if (info != null) 
              for (int i = 0; i < info.length; i++) 
                  if (info[i].getState() == NetworkInfo.State.CONNECTED)
                  {
                      return true;
                  }

      }
      return false;
   }
}

then before you execute your AysncTask:

 ConnectionDetector conn = new ConnectionDetector(getApplicationContext());
 if(conn.isConnectiontoInternet())
    new DownloadTextTask().execute("http://192.168.1.100/PHP_MVC/mobile/MLogin.php");
 else
    //show toast.

P.S: make sure you add this permission to your manifest:

<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Outras dicas

You're getting a null pointer exception. Check for nulls and then if you get a null value perform logic accordingly. Most importantly, you should check to see if you have a network connection prior to executing your network IO to help prevent these types of issues from occurring.

You can do this by following the solution listed in this question: Detect whether there is an Internet connection available on Android

This will happen if the InputStream in = null. If the network is down OpenHttpPOSTConnection will try to read from the network and will fail and throw and exception. You catch this. This will result in the function returning null, and inputstream will be null.

A null check of the return value of OpenHttpPOSTConnection will solve this

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top