I have made in .NET a web service method called “Login” and I have published it in my in my localhost(IIS). The method just takes 2 String parameters (Username and Password) checks in a database that I have in my sql server if there is a user that matches these parameters and if it finds someone returns 1, else it returns 0. From my browser it all works fine.
I tried to reach the method by an android app (at first just take the result and show it on the screen). Here is the code (I’ve found many bits from here and there):
public class LoginCheck extends Activity {
private static final String SOAP_ACTION = "http://tabtobook.org/Login";
private static final String METHOD_NAME = "Login";
private static final String NAMESPACE = "http://tabtobook.org/";
private static final String URL = "http://192.168.1.2/TabBookServices/Users.asmx";
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
/** Called when the activity is first created. */
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv=(TextView)findViewById(R.id.tv);
ServiceCall();
}
public void ServiceCall()
{
try{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
String A="user1";
request.addProperty("Username", A);
String B="user1";
request.addProperty("Password", B);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.setOutputSoapObject(request);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject result = (SoapObject)envelope.getResponse();
tv.setText(result.toString());
}
catch (final IOException e)
{
((TextView) findViewById(R.id.tView)).setText("test3");
e.printStackTrace();
} catch (final XmlPullParserException e)
{
e.printStackTrace();
} catch (final Exception e)
{
e.printStackTrace();
}
}
}
From my debugging so far, the program throws the “final Exception e” (the very last on my code) when it goes at the line “androidHttpTransport.call(SOAP_ACTION, envelope);”. From the WSDL I get:
targetNamespace="http://tabtobook.org/", location="http://localhost/TabBookServices/Users.asmx, soapAction="http://tabtobook.org/Login"
(I didn’t copy it all, cause I couldn't do it here for a reason. Anyway at the same web service there are other irrelevant methods) So I think that I got the NAMESPACE, METHOD_NAME, SOAP_ACTION and URL right. But being a newbie in soap I cannot be sure.
So what is wrong? Is the request envelop malformed, or do I use the androidHttpTransport wrong? (Or maybe both!)
EDIT: I put some lines from the logcat. I think it is the "android.os.NetworkOnMainThreadException" that throws the exception. Should I try something like an Asynchtask to handle it?
11-11 21:17:53.607: D/AndroidRuntime(4574): Shutting down VM 11-11 21:17:53.667: I/AndroidRuntime(4574): NOTE: attach of thread 'Binder Thread #3' failed 11-11 21:17:53.667: D/dalvikvm(4574): GC_CONCURRENT freed 102K, 77% free 483K/2048K, paused 1ms+3ms 11-11 21:17:53.667: D/dalvikvm(4574): Debugger has detached; object registry had 1 entries 11-11 21:17:54.117: W/System.err(4491): android.os.NetworkOnMainThreadException 11-11 21:17:54.237: W/System.err(4491): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1084) 11-11 21:17:54.237: W/System.err(4491): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:74) 11-11 21:17:54.248: W/System.err(4491): at libcore.io.IoBridge.connectErrno(IoBridge.java:127) 11-11 21:17:54.248: W/System.err(4491): at libcore.io.IoBridge.connect(IoBridge.java:112) 11-11 21:17:54.298: W/System.err(4491): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192) 11-11 21:17:54.298: W/System.err(4491): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459) 11-11 21:17:54.298: W/System.err(4491): at java.net.Socket.connect(Socket.java:842) 11-11 21:17:54.307: W/System.err(4491): at libcore.net.http.HttpConnection.(HttpConnection.java:77) 11-11 21:17:54.317: W/System.err(4491): at libcore.net.http.HttpConnection.(HttpConnection.java:50)
I did it using an Asynchtask: (I do not edit the first post so that everyting exists there)
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
String response = "";
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
String A="user2";
request.addProperty("Username", A);
String B="user2";
request.addProperty("Password", B);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.setOutputSoapObject(request);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject result = (SoapObject)envelope.bodyIn;
response=result.toString();
}
catch (Exception e) {
e.printStackTrace();
}
return response;
}
@Override
protected void onPostExecute(String result) {
tv.setText(result);
}
}
public void ServiceCall() {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute();
}
}
What I get in my screen is "LoginResponse{LoginResult=1;}" if the the user exists or "LoginResponse{LoginResult=0;}"if he does not. So the method works fine!
Now I have 2 problems to make it a login module as I want (of course I'll search for those):
I need a way to take just the result "0" or "1" from the method. Or I think maybe I could use the whole string. But when I try something like "if(result.equals("LoginResponse{LoginResult=1;}"))" it does not work (it does not get a true value). What is the problem?
I want the user to input the data. So I have to pass arguments to the AsyncTask. Is that possible? Or should I do the reading of the input (setting listener on a button), inside the AsyncTask class?
EDIT: for number 2 I found the answer here -> Android: How can I pass parameters to AsyncTask's onPreExecute()?
EDIT: for number 1 what was missing was just a space!
if(result.equals("LoginResponse{LoginResult=1; }"))
works fine! I'd like to know how to get the just the methods result (0 or 1) though. If someone knows please answer!