0

I am new to Android programming. I have gone through most of the Android developer docs by Google. Here is my question:

What i am trying to do: From the first Login page of my app, I am trying to fetch a json file located in a server and parse the results to check whether the login was successful or not. I am unable to parse the json in the following class. Please suggest what is wrong. I have checked all the other questions from past few days on stackoverflow but not much help. please help.

LoginActivity.java

package com.practice.serverdashboard;



import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.Service;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;

public class LoginActivity extends Activity {

    public EditText username;
    private EditText password;

    private static final String TAG = "MyActivity";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        username = (EditText) findViewById(R.id.txt_username);   
        password = (EditText) findViewById(R.id.txt_password);   

        //Showing the keypad
         InputMethodManager mgr = (InputMethodManager)this.getSystemService(Service.INPUT_METHOD_SERVICE);
         mgr.showSoftInput(username, InputMethodManager.SHOW_IMPLICIT);     
    }

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


    public void callLoginService(View v)
    {
        //Hidding the keypad
        InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        mgr.hideSoftInputFromWindow(username.getWindowToken(), 0);
        mgr.hideSoftInputFromWindow(password.getWindowToken(), 0);


        String loginUrlString="http://freakageekinternaltest.com:2200/mgmt/JSP/login.jsp?userId="+username.getText()+"&pws="+password.getText();
        Log.e("log_tag", "The URL is :: "+loginUrlString);
        //calling the login URL
        //GetJson gJ=new GetJson();
        //gJ.execute(loginUrlString);
        JSONObject json=getJSONfromURL(loginUrlString);


        AlertDialog.Builder adb = new AlertDialog.Builder(
                LoginActivity.this);
                adb.setTitle("Login Service");
                adb.setMessage("Testing...");
                adb.setPositiveButton("Ok", null);
                adb.show(); 


    }



public JSONObject getJSONfromURL(String url){

    //initialize
    InputStream is = null;
    String result = "";
    JSONObject jArray = null;

    //http post
    try{
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(url);
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        is = entity.getContent();

    }catch(Exception e){
        Log.e("log_tag", "Error in http connection "+e.toString());
    }

    //convert response to string
    try{
        BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        result=sb.toString();

        Log.e("log_tag", "result is:: "+result);

    }catch(Exception e){
        Log.e("log_tag", "Error converting result "+e.toString());
    }

    //try parse the string to a JSON object
    try{
            jArray = new JSONObject(result);
    }catch(JSONException e){
        Log.e("log_tag", "Error parsing data "+e.toString());
    }

    AlertDialog.Builder adb = new AlertDialog.Builder(
            LoginActivity.this);
            adb.setTitle("Login Service");
            adb.setMessage("Success...");
            adb.setPositiveButton("Ok", null);
            adb.show(); 

    return jArray;
}

}

Here is the logcat output:

02-13 11:13:15.173: E/log_tag(6083): The URL is :: http://freakageekinternaltest.com:2200/mgmt/JSP/login.jsp?userId=test567&pws=test@pps
02-13 11:13:15.183: E/log_tag(6083): Error in http connection android.os.NetworkOnMainThreadException
02-13 11:13:15.183: E/log_tag(6083): Error converting result java.lang.NullPointerException: lock == null
02-13 11:13:15.183: E/log_tag(6083): Error parsing data org.json.JSONException: End of input at character 0 of 

I have checked out the AsyncTask also, because of the NetworkOnMainThreadException exception( with help from stackoverflow). But i dont know where to start and how to use Async class in my LoginActivity.java class. Please help. Thanking you in advacnce.

Here is the json that i am trying to fetch from a server and parse:

{"LOGIN":"TRUE","userId":"Web Administrator","userAccessType":"ALL"}

@gabe: thx for ur early reply gabe. Is it mandatory to do networking operations in the background? Since i am trying to fetch login details from server, what will my app will do when it just sits there waiting for the server response? Also, considering my above code, what to do to implement AsyncTask class? I have gone through the docs mentioned by u. But i tried making a new class which extends AsyncTask. In that class, i did all the networking operation in the doInBackground method and thn used the onPostExecute method to send back the results to LoginActivity.java class. However, since this background operations are done on a new class which extends the AsyncTask class, so i am unable to use the controls defined in my main_activity.xml file. So how to implement all this? Thx again.

Hello again! Now i have modified my code as suggested in the answers.

private class RetreiveDataAsynctask extends AsyncTask<String,Void,JSONObject> {

        @Override
        protected JSONObject doInBackground(String... loginURL) {
            JSONObject obj = getJSONfromURL(loginURL);
            return obj;
        }

        @Override
        protected void onPostExecute(JSONObject obj) {
             //Do all ur UI related stuff as this will be executing in ui thread

            super.onPostExecute(obj);
        }


    }

And in the onCreate method, i am calling like this:

RetreiveDataAsynctask mRetreiveData = new RetreiveDataAsynctask();
        mRetreiveData.execute(loginUrlString);

But, its giving error in this line:

JSONObject obj = getJSONfromURL(loginURL);

Can somebody tell me what is wrong with this code? The rest of the parsing functions remains same as specified above. Thx in advance.

Mrinal Mandal
  • 235
  • 2
  • 11
  • refer from this , it may help you. http://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-and-sqlite/ – saran Feb 13 '13 at 11:31
  • This is just a system library, not a court of judges. If you try networking on the main thread, it throws an exception regardless if you have best reasons to do this, or worst reasons, no lawyering can help. – Audrius Meškauskas Feb 13 '13 at 11:56
  • @ Audrius Meškauskas: that means we just jave to follow this rule, but its not mandatory? we may skip this rule if we have some requirements? – Mrinal Mandal Feb 13 '13 at 12:01

4 Answers4

1

The error

Error in http connection android.os.NetworkOnMainThreadException

indicates that you are doing your work on the main thread but you should do it in a separate thread, because your network operation blocks the User Interface.

You could use a AsyncTask to do your network operations.

Take a look at Process & threads in Android for more information.

Look at this AsyncTask Example for more information.

Community
  • 1
  • 1
n3utrino
  • 2,361
  • 3
  • 22
  • 32
  • tx for ur reply. pls check my edit and see what is wrong. thx again. – Mrinal Mandal Feb 13 '13 at 11:44
  • i did edit my answer with a async task example. I won't post code, I just give hints. The concept of offloading long tasks to the background is crucial to understand in (android) programming. – n3utrino Feb 13 '13 at 11:52
  • thx for the example. i am just checking it. If it helps, then i will select this as the right answer. thx again. – Mrinal Mandal Feb 13 '13 at 11:56
1

Make asynctask like this :

private class RetreiveDataAsynctask extends AsyncTask<String loginUrlString, Void, JSONObject> {

    @Override
    protected Response doInBackground(Void... params) {
        JSONObject obj = getJSONfromURL( loginUrlString);
        return obj;
    }

    @Override
    protected void onPostExecute(JSONObject obj) {
         //Do all ur UI related stuff as this will be executing in ui thread

        super.onPostExecute(result);
    }


}

and then in ur OnCreate

RetreiveDataAsynctask mRetreiveData = new RetreiveDataAsynctask();
        mRetreiveData.execute();
user1969053
  • 1,750
  • 1
  • 12
  • 12
  • Thx for ur reply. Where to write this file? In the LoginActivity.java file itself or do i need to make a separate file called RetreiveDataAsynctask.java? Since RetreiveDataAsynctask is a different class from my LoginActivity.java, so will i be able to access my UI related stuff from this class? thx. – Mrinal Mandal Feb 13 '13 at 11:53
  • In ur LoginActivity.java file define this class RetreiveDataAsynctask.and in OnCreate of ur LoginActivity.java do this mRetreiveData.execute(); – user1969053 Feb 13 '13 at 11:58
  • Yes, i have done this as suggested by you. In LoginActivity.java, i have: RetreiveDataAsynctask mRetreiveData = new RetreiveDataAsynctask(); mRetreiveData.execute(loginUrlString); => this will return a json object. Right? So, if i want to store this json object for parsing/other operations, i write like this: JSONObject json=mRetreiveData.execute(loginUrlString);=> why this is giving error? Waiting for ur reply. Thx. – Mrinal Mandal Feb 13 '13 at 14:15
0

Try this:

class Communicator extends AsyncTask<String, String, String> 
    {
        @Override
        protected String doInBackground(String... params) {
            //Here call the method for parsing
        }

        @Override
        protected void onPreExecute() 
        {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String result) 
        {
            super.onPostExecute(result);
        }
    }

//And on callLoginService(View v) you start the AsyncTask
        //if you want to pass some value
        String values[] = { userna, passwo };
        new Communicator().execute(values); 
        //Otherwise
        new Communicator().execute(); 
user1744952
  • 508
  • 1
  • 3
  • 15
  • ok..just going to try this. Can u tell me what are these params in AsyncTask? why u have used String? why not void or Long or int? i have seen in many places people using different things in different scenarios. exactly what we have to look for? – Mrinal Mandal Feb 13 '13 at 11:59
  • Ok to be clear about parameters, check this link http://stackoverflow.com/questions/6053602/what-arguments-are-passed-into-asynctaskarg1-arg2-arg3 – user1744952 Feb 13 '13 at 12:03
0

Use Async Task to get Json from url.. or Add below two line in your method

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); 
Vamshi
  • 1,495
  • 1
  • 15
  • 31
  • (╯°□°)╯︵ ┻━┻ This is a really bad suggestion. If you must post it at least explain why it is bad and how to do it right. – n3utrino Feb 13 '13 at 11:41