I'm new to ksoap2 and I'm trying to get example w3 schools example working. For some reason it always fails on this line.
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
I dont know what is causing the fail. The android app just blows up. I have set internet permisions in Manifest. Im not really sure what is going on. Thanks
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.Toast;
public class WebServiceTurorialActivity extends Activity implements OnClickListener{
private static final String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private static final String METHOD_NAME = "CelsiusToFahrenheit";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
(findViewById(R.id.button1)).setOnClickListener(this);
}
public void onClick(View v) {
int a;
int b;
try
{
// EditText ed1=(EditText)findViewById(R.id.editText1);
// EditText ed2=(EditText)findViewById(R.id.editText2);
// a = Integer.parseInt(ed1.getText().toString());
// b = Integer.parseInt(ed2.getText().toString());
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
//Request.addProperty("a", a);
// Request.addProperty("b", b);
Request.addProperty("Celsius", "32");
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(Request);
HttpTransportSE transport= new HttpTransportSE(URL);
transport.call(SOAP_ACTION, soapEnvelope);
SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();
Toast.makeText(this,"200 " + resultString,Toast.LENGTH_SHORT).show();
}catch(Exception ex) {
Toast.makeText(this,"FALSE",Toast.LENGTH_SHORT).show();
}
}
}
I had the same problem. That works for me:
As the prev answer said:
In your build path clear all libraries (jar files).
In project's main directory create a folder and named it "libs" (not "lib").
Now Eclipse ADT Plugin will add your jar files to build path
Not realy for me. My way:
In your build path remove the "ksoap2-android-assembly-2.x.x-jar-with-dependencies.jar"
Click OK (Ignore Errors shown)
In project's main directory create a folder "libs"
Copy the JAR-File into this directory (!)
In your build path add the JAR file with this directory
For everyone having also this problem... I was trying to solve this problem for many many hours, but then I detected what my fault was: I did not correctly download the ksoap2 library, so there was only a jar file which was 21 KB, but the correct jar file is about 150KB. So make sure that you download the file correctly!
In your build path clear all libraries (jar files).
In project's main directory create a folder and named it "libs" (not
"lib").
Now Eclipse ADT Plugin will add your jar files to build path.
Happy coding
If you still get the same problem, try these classes (works for me):
public class Main extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String fahrenheit = CelsiusToFahrenheitWs.celsiusToFahrenheit("32");
Toast.makeText(getApplicationContext(), fahrenheit, Toast.LENGTH_SHORT).show();
}
}
And
public class CelsiusToFahrenheitWs {
private static final String METHOD_NAME = "CelsiusToFahrenheit";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private static final String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
public static String celsiusToFahrenheit(String celsius) {
String fahrenheit = null;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Celsius", celsius);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
fahrenheit = response.toString();
} catch (Exception e) {
e.printStackTrace();
fahrenheit = null;
}
return fahrenheit;
}
}
I've created an another SOAP library to call SOAP services on Android, the name of the project is AndroidSOAP ( http://wiki.javaforum.hu/display/ANDROIDSOAP/Home ).
I've released a version 0.0.5 today, check it out: http://wiki.javaforum.hu/display/ANDROIDSOAP/2012/05/01/Version+0.0.5+released
W3Schools.com is no more accepting NAMESPACE as tempuri.org which caused SOAP exception in the code. You need to use "http://www.w3schools.com/webservices/" for NAMESPACE and "http://www.w3schools.com/webservices/CelsiusToFahrenheit" for SOAP_ACTION.
Hope this is help!
Related
I try to create android login web service with java. I am using Axis2.
I am developing web service with Eclipse EE and android application with Eclipse Adt Bundle. I can access "http://localhost:8081/Login/services/Login?wsdl" page. When android application ran and clicked login button, i am not seeing any message (issued inside web services status="success" or status="login fail")on the screen.
I didn't solve this problem.Any help will be appreciated.
Web Service:
package com.userlogin.ws;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Login {
public String authentication(String userName, String password) {
String retrievedUserName = "";
String retrievedPassword = "";
String status = "";
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/places", "root",
"");
PreparedStatement statement = con
.prepareStatement("SELECT * FROM user WHERE username = '"
+ userName + "'");
ResultSet result = statement.executeQuery();
while (result.next()) {
retrievedUserName = result.getString("username");
retrievedPassword = result.getString("password");
}
if (retrievedUserName.equals(userName)
&& retrievedPassword.equals(password)) {
status = "Success!";
}
else {
status = "Login fail!!!";
}
} catch (Exception e) {
e.printStackTrace();
}
return status;
}
}
Android:
package com.androidlogin.ws;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class AndroidLoginExampleActivity extends Activity {
private final String NAMESPACE = "http://ws.userlogin.com";
private final String URL = "http://localhost:8081/Login/services/Login?wsdl";
private final String SOAP_ACTION = "http://ws.userlogin.com/authentication";
private final String METHOD_NAME = "authentication";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button login = (Button) findViewById(R.id.btn_login);
login.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
loginAction();
}
});
}
private void loginAction(){
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
EditText userName = (EditText) findViewById(R.id.tf_userName);
String user_Name = userName.getText().toString();
EditText userPassword = (EditText) findViewById(R.id.tf_password);
String user_Password = userPassword.getText().toString();
//Pass value for userName variable of the web service
PropertyInfo unameProp =new PropertyInfo();
unameProp.setName("userName");//Define the variable name in the web service method
unameProp.setValue(user_Name);//set value for userName variable
unameProp.setType(String.class);//Define the type of the variable
request.addProperty(unameProp);//Pass properties to the variable
//Pass value for Password variable of the web service
PropertyInfo passwordProp =new PropertyInfo();
passwordProp.setName("password");
passwordProp.setValue(user_Password);
passwordProp.setType(String.class);
request.addProperty(passwordProp);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try{
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
TextView result = (TextView) findViewById(R.id.tv_status);
result.setText(response.toString());
}
catch(Exception e){
}
}
}
You are squashing exceptions in the android code:
catch(Exception e){
}
There's a good chance that that is discarding the evidence that would tell you what the underlying problem is. Either way, squashing Exception like that is very bad practice.
In android code you trying to connect to localhost, but it should a host name where the java service running. In the android device you obviously don't have any service available on port 8081.
This is quite a common mistake. Usually you develop server side and android application on the same machine so when running a service on localhost you believe that the same service should be available in the android application. However, in the emulator, the localhost is the address of the android device. The easiest way to develop and test such applications is to use ip address of the host machine.
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 9 years ago.
I have a aspx page that I am calling from my android app that is returning JSON text but the java code below breaks here BufferedReader reader = new BufferedReader(new InputStreamReader(jc.getInputStream()));
with this error.
error android.os.NetworkOnMainThreadException
ARe you able to help plesae? Thanks
default.aspx return json
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "text/plain";
//Write the message
Response.Write("{'testvar':'testtext'}");
//End the response causing it to be sent
Response.End();
}
}
android java
public void connectWCF() {
try {
URL json = new URL("http://localhost:50851/Default.aspx");
URLConnection jc = json.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(jc.getInputStream()));
String line = reader.readLine();
reader.close();
} catch(Exception e){
}
links where I got the code ideas from
http://wyousuf.wordpress.com/2012/03/01/android-with-wcf-services/
http://matijabozicevic.com/blog/android-development/android-with-wcf-service
You are placing network communication on the main thread. You should use AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
here's a nice video that explains JSON Parsing using AsyncTask.
http://www.youtube.com/watch?v=qcotbMLjlA4
For testing ONLY you can add the following in your Main Activity but it is consider bad practice.
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Since android 3.0, you can't put any calls to webpages or similar external resources in the main thread (in other words, any part of the activity) unless you do it with an AsyncTask, in order to avoid apps to look "locked" and unresponsive when waiting for a response from an external datasource. Therefore, you'll need to implement the webservice call with and AsyncTask.
Example class for AsyncTask:
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
public class cargaDatosRest extends AsyncTask<Context, Void, Void> {
private Context c;
private boolean resul = false;
private String control = "";
private String respStrS = "";
public cargaDatosRest(Context C)
{
c = C;
}
public String getStr()
{
return respStrS;
}
public String getControl()
{
return control;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//mProgressDialog.show();
}
#Override
protected Void doInBackground(Context... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpGet get = new HttpGet("url");
HttpResponse resp;
get.setHeader("content-type", "application/json");
try
{
/*resp contains the response from the webService. respStr and respJSON allows to read that resp in JSON format. Just delete them if you don't need them. You can asign the values returned by the webservice to local variables in the AsyncTask class and then read them with public methods, like the resul variable.*/
resp = httpClient.execute(getUsuarios);
String respStr = EntityUtils.toString(resp.getEntity());
JSONArray respJSON = new JSONArray(respStr);
this.resul = true;
}
catch(Exception ex)
{
Log.e("ServicioRest","Error!", ex);
this.resul = false;
}
}
public boolean getResul()
{
return this.resul;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
//mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(Void unused) {
//mProgressDialog.dismiss();
}
}
//calling the AsyncTask from the activity:
CargaDatosRest CallRest = new CargaDatosRest(this.getApplicationContext());
CallRest.execute();
Log.v("WebService", "Just trying "+arest.getResul());
I'm pretty new to android, please forgive any mistake.
package net.schwiz.oauth;
import org.json.JSONException;
import org.json.JSONObject;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.TwitterApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
public class Main extends Activity {
final static String APIKEY = "XXXXXXXXXXXXXXXXXXXX";
final static String APISECRET = "XXXXXXXXXXXXXXXXXXXX";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView textView = (TextView)findViewById(R.id.textview);
final WebView webview = (WebView) findViewById(R.id.webview);
if(APIKEY == null || APISECRET == null){
textView.setText("You must enter your own APIKEY and SECRET to use this demo. dev.twitter.com");
webview.setVisibility(View.GONE);
return;
}
//set up service and get request token as seen on scribe website
//https://github.com/fernandezpablo85/scribe-java/wiki/Getting-Started
final OAuthService s = new ServiceBuilder()
.provider(TwitterApi.class)
.apiKey(APIKEY)
.apiSecret(APISECRET)
.callback(CALLBACK)
.build();
final Token requestToken = s.getRequestToken();
final String authURL = s.getAuthorizationUrl(requestToken);
//attach WebViewClient to intercept the callback url
webview.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//check for our custom callback protocol otherwise use default behavior
if(url.startsWith("oauth")){
//authorization complete hide webview for now.
webview.setVisibility(View.GONE);
Uri uri = Uri.parse(url);
String verifier = uri.getQueryParameter("oauth_verifier");
Verifier v = new Verifier(verifier);
//save this token for practical use.
Token accessToken = s.getAccessToken(requestToken, v);
if(uri.getHost().equals("twitter")){
OAuthRequest req = new OAuthRequest(Verb.GET, "URL here");
s.signRequest(accessToken, req);
Response response = req.send();
try {
JSONObject json = new JSONObject(response.getBody());
textView.setText(json.toString(3));
} catch (JSONException e) {
e.printStackTrace();
}
}
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
});
//send user to authorization page
webview.loadUrl(authURL);
}
}
I tried this code, its working fine with twitter, but now i want to authenticate user using Flickr, The above code is not working in that case, the if condition if(url.startsWith("oauth")) is not working the way I supposed. Please help.
I've figured out the problem! When I call the method webview.loadUrl(authURL); the url of flickr www.flickr.com changes to m.flickr.com which triggers the event shouldOverrideUrlLoading before any user login/authentication.
if(authURL.charAt(7)=='w')
{
authURL=authURL.replaceFirst("www", "m");
}
solved my problem.
Anyone who's struggling to get this to work with more recent version of Android, I have a gist that can be found here. This uses Scribe and Flickr4J because Scribe does not have a facility AFAIK to create a requestToken for auth with a callback. One of the things to note here is that the code above will not work as is with more recent version of Android since it no longer allow network tasks in the UI thread...and I addressed this in the gist through the use of (the recently deprecated AsyncTask)
I have developed a WCF Service .NET4 and I am trying to connect to it from Android(1.6). But when i try to connect all i get is "org.xmlpull v1 xmlpullparserexception unexpected type (position: END_DOCUMENT null#1:0 in java.io.InputStreamReader#4396aa90)" error.. I've already checked METHOD_NAME , NameSpace, URL , Soap_Action and look fine for me. Also i tried with System.setProperty("http.keepAlive", "false") and changing SoapEnvelope.VER from 10 to 12 but still nothing.. Any suggestions?
My code:
package web.service;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.ksoap2.*;
import org.ksoap2.serialization.*;
import org.ksoap2.transport.*;
import org.w3c.dom.Text;
public class WebServiceConnActivity extends Activity {
private static final String NAMESPACE = "http://tempuri.org/" ;
private static final String URL = "http://10.0.2.2:51599/Service.svc";
//private static final String URL = "http://10.0.2.2:51599/MyWCFApp/Service.svc";
private static final String Add_SOAP_ACTION = "http://tempuri.org/IService/HelloWorld";
private static final String METHOD_NAME1 = "HelloWorld";
public TextView tView;
public Button btn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tView = (TextView)findViewById(R.id.tView);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
GetAdd();
}
});
}
public void GetAdd()
{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);
//request.addProperty("value1", "2");
//request.addProperty("value2", "3");
SoapSerializationEnvelope envelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
System.setProperty("http.keepAlive", "false");
try
{
androidHttpTransport.call(Add_SOAP_ACTION, envelope);
//java.lang.String receivedInt = (String)envelope.getResponse();
Object result = (Object)envelope.getResponse();
tView.setText(result.toString());
}
catch(Exception e)
{
tView.setText(e.toString());
}
}
}
I've spent little more time on this problem and here's what come into my mind:
The problem is probably in URL - I've developed WS .NET3.5 and all works just fine, and only difference is URL:
private static final String URL = "http://10.0.2.2:50915/aspWebService/Service.asmx";
But I have no clue where i could make mistake in WCF's URL. I took URL from WDSL and i just change "localhost" to "10.0.2.2", the address http://10.0.2.2:51599/Service.svc is visible from emulators browser.
Here is part of my WDSL file with URL(i suppose):
<wsdl:service name="Service">
<wsdl:port name="WSHttpBinding_IService" binding="tns:WSHttpBinding_IService">
<soap12:address location="http://localhost:51599/Service.svc"/>
<wsa10:EndpointReference>
<wsa10:Address>http://localhost:51599/Service.svc</wsa10:Address>
<Identity>
<Dns>localhost</Dns>
</Identity>
</wsa10:EndpointReference>
</wsdl:port>
</wsdl:service>
Any hints?
If your web service is returning a complex object (maybe a String) then try this:
SoapObject response = (SoapObject)envelope.getResponse();
String string = response.toString();
instead of this:
Object result = (Object)envelope.getResponse();
Problem solved.
If you are using Visual Studio's Development Server to test the WCF service, you may need to deploy the service to IIS. How to do it you will find at: http://msdn.microsoft.com/en-us/library/aa751792.aspx
Then make changes in NAMESPACE, URL
private static final String NAMESPACE = "http://tempuri.org/" ;
private static final String URL = "http://MyWCFApp/Service.svc";
I am running the YouTubeSample given on the google developers website. I have no errors in the code and my imports appear to be fine. But when I run the project I get the aforementioned error.
I have done some searches but to be honest I have been unable to work out what the problem is. I have already tried importing an external jar guava but it didn't help.
Any help is appreciated. Here is the full class
package com.pengilleys.googlesamples;
import java.io.IOException;
import java.util.List;
import com.google.api.client.googleapis.GoogleHeaders;
import com.google.api.client.googleapis.json.JsonCParser;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.client.util.Key;
public class YouTubeSample {
public static class VideoFeed {
#Key List<Video> items;
}
public static class Video {
#Key String title;
#Key String description;
#Key Player player;
}
public static class Player {
#Key("default") String defaultUrl;
}
public static class YouTubeUrl extends GenericUrl {
#Key final String alt = "jsonc";
#Key String author;
#Key("max-results") Integer maxResults;
YouTubeUrl(String url) {
super(url);
}
}
public static void main(String[] args) throws IOException {
// set up the HTTP request factory
HttpTransport transport = new NetHttpTransport();
final JsonFactory jsonFactory = new JacksonFactory();
HttpRequestFactory factory = transport.createRequestFactory(new HttpRequestInitializer() {
#Override
public void initialize(HttpRequest request) {
// set the parser
JsonCParser parser = new JsonCParser();
parser.jsonFactory = jsonFactory;
request.addParser(parser);
// set up the Google headers
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName("Google-YouTubeSample/1.0");
headers.gdataVersion = "2";
request.headers = headers;
}
});
// build the YouTube URL
YouTubeUrl url = new YouTubeUrl("https://gdata.youtube.com/feeds/api/videos");
url.author = "searchstories";
url.maxResults = 2;
// build the HTTP GET request
HttpRequest request = factory.buildGetRequest(url);
// execute the request and the parse video feed
VideoFeed feed = request.execute().parseAs(VideoFeed.class);
for (Video video : feed.items) {
System.out.println();
System.out.println("Video title: " + video.title);
System.out.println("Description: " + video.description);
System.out.println("Play URL: " + video.player.defaultUrl);
}
}
}
The setup documentation gives a list of dependencies:
Depending on the application you are building, you may also need these dependencies:
Apache HTTP Client version 4.0.3
Google Guava version r09
Jackson version 1.6.7
Google GSON version 1.6
In this case, it looks like it's Guava which is missing. I don't know what you mean about "exporting" Guava, but if you include the Guava r09 jar file in the classpath when you're running the code, it should be fine.
what's the extra ); for above the // build the YouTube URL and did you mean to close main on that line?