WSDL calling from Android causes NetworkOnMainThreadException - android

Here is this sample code (MainActivity):
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";
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.text1);
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Celsius", "32");
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(request);
HttpTransportSE aht = new HttpTransportSE(URL);
try {
aht.call(SOAP_ACTION, soapEnvelope);
SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();
tv.setText("Status: " + resultString);
} catch (Exception e) {
tv.setText("Problem: " + e.toString());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
...
When I run this code I got this message Problem: android.os.NetworkOnMainThreadException.
In the manifest.xml added the
<uses-permission android:name="android.permission.INTERNET" />
line.
Here
is the whole android project.
Does someone have any idea how to change this code?
Thank you in advance for any help you can provide.

This exception is thrown when an android application attempts to perform a network operation on its main thread. You must run your code in AsyncTask. Your code will look something like this
You can declare resultString as an instance variable
class SoapTask extends AsyncTask<String, Void, Void> {
private Exception exception;
#Override
protected Void doInBackground(Void... arg0) {
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Celsius", "32");
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(request);
HttpTransportSE aht = new HttpTransportSE(URL);
try {
aht.call(SOAP_ACTION, soapEnvelope);
resultString = "Status:" + (SoapPrimitive)soapEnvelope.getResponse();
} catch (Exception e) {
resultString = "Problem:" + e.toString();
}
}
protected void onPostExecute(Void result) {
tv.setText("Status: " + resultString);
}
}

Try this..
NetworkOnMainThreadException throws when you are performing network operation on its main thread.
So you have to run you network operations in AsyncTask
You can call AsyncTask like below
new SerializationConnection().execute(URL);
then SerializationConnection class
class SerializationConnection extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Celsius", "32");
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(request);
HttpTransportSE aht = new HttpTransportSE(urls[0]);
aht.call(SOAP_ACTION, soapEnvelope);
SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();
return "Status: " + resultString;
} catch (Exception e) {
return "Problem: " + e.toString();
}
}
protected void onPostExecute(String result) {
tv.setText(result);
}
}

You are making a server call in main thread.if your target version is 9
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
For Better way try to use AsynTask

Related

Image loading using picasso library from url

initially, I am fetching image URL from server to a string then using Picasso library I am trying to load the image
I am able to get image URL from the server like thislogcat
but image not loaded in the image view. when tried placing direct URL it works.
public class MainActivity extends AppCompatActivity {
ImageView im;
Button bm;
String str ;
private static String NAMESPACE = "http://telview360/";
private static String URL = "http://54.179.134.139/viView360Service/WebService.asmx?WSDL";
private static String SOAP_ACTION = "http://telview360/ImageDetails";
private static String METHOD_NAME = "ImageDetails";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.load_image);
final Thread networkThread = new Thread() {
#Override
public void run() {
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE ht = new HttpTransportSE(URL);
ht.call(SOAP_ACTION, envelope);
final SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
str = response.toString();
Log.d("Webservice", " response " + str);
} catch (Exception e) {
e.printStackTrace();
}
}
};
networkThread.start();
bm = (Button) findViewById(R.id.btn_load_image);
bm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
im = (ImageView) findViewById(R.id.image);
Picasso.with(getApplicationContext()).load(str).into(im);
}
});
}
}
add this to your code
final Thread networkThread = new Thread() {
#Override
public void run() {
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE ht = new HttpTransportSE(URL);
ht.call(SOAP_ACTION, envelope);
final SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
str = response.toString();
Log.d("Webservice", " response " + str);
} catch (Exception e) {
e.printStackTrace();
}
}
};
networkThread.start();
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
it will work

Async Task with multiple requests in android

I am using this asynctask Class to update two different tables on Sql Server so far this code works fine i'm interested in more better and sufficient code structure of this class specially in doinbackground() Is it okay to call multiple webservices methods in a single thread? can any one suggest me?
private class Update extends AsyncTask<Void, Void, Integer> {
private final int FAILED_INVALID_RESPONSE = 0;
private final int SUCCESS_GET_DATA = 1;
ProgressDialog progress;
private String _phoneno;
private String _ticket;
UpdateTicket(String phoneno,String ticket){
_phoneno=phoneno;
_ticket=ticket;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progress = ProgressDialog.show(XYZ.this, "",
"In Progress...", false);
}
#Override
protected Integer doInBackground(Void... params) {
method1(_phoneno);
return method2(_phoneno,_ticket);
}
#Override
protected void onPostExecute(Integer result) {
progress.dismiss();
switch (result) {
case FAILED_INVALID_RESPONSE:
Toast.makeText(XYZ.this,"Please Check your Internet Connection.",Toast.LENGTH_SHORT).show();
break;
case SUCCESS_GET_DATA:
Toast.makeText(XYZ.this, "Success!", Toast.LENGTH_SHORT).show();
break;
}
}
int method1(String phoneno,String tickets)
{
final String methodname = "firstmethod";
final String NAMESPACE ="http://tempuri.org/";
final String URL="www.sampleurl.com";
final String SOAP_ACTION="http://tempuri.org/firstmethod";
int success=0;
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
SoapObject request = new SoapObject(NAMESPACE, methodname);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
request.addProperty("phoneno", phoneno);
request.addProperty("tickets", tickets);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try{
androidHttpTransport.call(SOAP_ACTION,envelope);
SoapObject response = (SoapObject) envelope.bodyIn;
if(response!=null){
success=1;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return success;
}
int method2(String Phone) {
final String methodname = "secondmethod";
final String NAMESPACE ="http://tempuri.org/";
final String URL="www.sampleurl.com";
final String SOAP_ACTION="http://tempuri.org/secondmethod";
int success=0;
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
SoapObject request = new SoapObject(NAMESPACE, methodname);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
request.addProperty("phoneno", phoneno);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try{
androidHttpTransport.call(SOAP_ACTION,envelope);
SoapObject response = (SoapObject) envelope.bodyIn;
if(response!=null){
success=1;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return success;
}
}
AsyncTask should only be used for tasks/operations that take quite few seconds.
AsyncTasks are executed serially on a single background thread (from API 11). So long running worker can block others.
Check some other gotchas.
Take a look at HeandlerThread.

SOAP webservice calling using Ksoap

I am trying to call a soap which looks like this in SOAPUI. It's having 4 parameter. url is - http://seycel.com.mx/ws/res2.php
Inputs are like this-
`<usuario xsi:type="xsd:string">1212121212</usuario>
<sms xsi:type="xsd:string">saldo</sms>
<palabra xsi:type="xsd:string">0439267236</palabra>
<fecha xsi:type="xsd:string">2015-05-20 20:10:10</fecha>`
I want to call this from android and fetch the return tag. What I am trying to do is like this -
private static final String SOAP_ACTION = "urn:recargas#saldo";
private static final String METHOD_NAME = "saldo";
private static final String NAMESPACE = "urn:recargas";
private static final String URL = "http://seycel.com.mx/ws/res2.php?wsdl";
private class UserRegistrationTask extends AsyncTask<String, String, String> {
protected String doInBackground(String... values) {
SoapPrimitive result = null;
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("palabra", "0439267236");// Parameter for Method
request.addProperty("usuario", "1212121212");// Parameter for Method
request.addProperty("sms", "saldo");// Parameter for Method
request.addProperty("fecha", "15-05-30 20:52:20");// Parameter for Method
SoapSerializationEnvelope envelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
result = (SoapPrimitive) envelope.getResponse();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return result.toString();
}
protected void onPostExecute(String result) {
Log.d("TAG", "value: " + result);
}
}
getting an error like this java.lang.String cannot be cast to org.ksoap2.serialization.SoapPrimitive

android app connect to magento via soap webservice

i am a android app developer. and i want to connect my android with magento with soap web service.
i run this code but i can't get the session id.
so please help me to how i get the session id and if this code has something wrong then please correct this.
public class MainActivity extends Activity
{
private static final String SOAP_ACTION ="urn:Mage_Api_Model_Server_HandlerAction";
private static final String NAMESPACE = "urn:Magento";
private static final String Method_Name="login";
private static final String URL ="http://abcd.com/api/v2_soap/";
TextView tv;
Context mContext;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView)findViewById(R.id.tv);
}
public class getData extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
SoapObject request = new SoapObject(NAMESPACE,Method_Name);
request.addProperty("username", "suman");
request.addProperty("apiKey", "suman123");
SoapSerializationEnvelope envelopes = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelopes.dotNet = false;
envelopes.setOutputSoapObject(request);
try
{
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
androidHttpTransport.debug =true;
androidHttpTransport.call(SOAP_ACTION, envelopes);//Getting the Exception here
SoapPrimitive resultString=(SoapPrimitive)envelopes.getResponse();
tv.setText("Status "+resultString);
new AlertDialog.Builder(mContext).setMessage(""+resultString).show();
}
catch (Exception e) {e.printStackTrace();
new AlertDialog.Builder(mContext).setMessage(""+e.toString()).show();
}
return null;
}
}
}
i get sessionID with this code :
private static final String NAMESPACE = "urn:Magento";
private static final String URL = "http://your_domain/index.php/api/v2_soap/";
SoapSerializationEnvelope env;
HttpTransportSE androidHttpTransport;
SoapObject request;
String sessionId = "";
Object result;
env = new SoapSerializationEnvelope(SoapEnvelope.VER11);
env.dotNet = false;
env.xsd = SoapSerializationEnvelope.XSD;
env.enc = SoapSerializationEnvelope.ENC;
SoapObject request = new SoapObject(NAMESPACE, "login");
request.addProperty("username", "xxxxx");
request.addProperty("apiKey", "123456");
env.setOutputSoapObject(request);
androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
(new MarshalHashtable()).register(env);
androidHttpTransport.call("", env);
result = env.getResponse();
Log.d("sessionId", result.toString());
sessionId = result.toString();
v2_soap is not working in your magento framework . So you better go with SOAP with the version 1.
use this
http://abcd.com/api/soap/
and give appropriate permissions for your android application project . like Internet , Wifi state if you are using , bluethooth is also needed , Network state ,
if you are using android studio , then paste this code in your MainActivity
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
Try this class... its working for me...I am using Android ksoap2 library...
private static final String NAMESPACE = "urn:Magento";
private static final String URL = "http://localhost:8888/Magento/index.php/api/v2_soap/";
private class magentoUserlogin extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
Object result= null;
try {
SoapSerializationEnvelope env = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
env.dotNet = false;
env.xsd = SoapSerializationEnvelope.XSD;
env.enc = SoapSerializationEnvelope.ENC;
SoapObject request = new SoapObject(NAMESPACE, "login");
request.addProperty("username", "<urSOAP/XML username>");
request.addProperty("apiKey", "<yourAPIKey>");
env.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call("", env);
result = env.getResponse();
} catch (Exception e) {
e.printStackTrace();
}
return result.toString();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("sessionId", s.toString());
Toast.makeText(MainActivity.this, "Session ID: "+s, Toast.LENGTH_LONG).show();
}
}

Android Soap Web service Error behind Proxy Server

I have written a program for communicating with a web service and get response value. But when i debug the programme i end with requestDump=null at the line androidHttpTransport.call(SOAP_ACTION, envelope); Can some one tell me the reason for the error and what can i do for this
public class WebService extends Activity {
private final String NAMESPACE = "http://tempuri.org/";
private final String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
private final String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private final String METHOD_NAME = "CelsiusToFahrenheit";
String celsius;
Button b;
TextView tv;
EditText et;
String res,resultval;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_service);
et=(EditText)findViewById(R.id.editText1);
tv=(TextView)findViewById(R.id.Result);
b=(Button)findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//String result=getFarenheit(et.getText().toString());
//tv.setText(result+"°F");
new service().execute();
}
});
}
private class service extends AsyncTask<Void, Void, String>{
#Override
protected String doInBackground(Void... arg0) {
celsius=et.getText().toString();
SoapObject request= new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo celsuiusPI= new PropertyInfo();
celsuiusPI.setName("Celsius");
celsuiusPI.setValue(celsius);
celsuiusPI.setType(String.class);
request.addProperty("XMLMarks",celsuiusPI);
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope (SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.implicitTypes = true;
envelope.enc = SoapSerializationEnvelope.ENC2003;
envelope.xsd = SoapEnvelope.XSD;
envelope.xsi = SoapEnvelope.XSI;
envelope.setOutputSoapObject(request);
envelope.setAddAdornments(false);
SoapPrimitive response;
HttpTransportSE androidHttpTransport=new HttpTransportSE(URL);
try{
androidHttpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
androidHttpTransport.debug = true;
androidHttpTransport.call(SOAP_ACTION, envelope);
String dump= androidHttpTransport.requestDump.toString();
response=(SoapPrimitive)envelope.getResponse();
Toast.makeText(WebService.this, response.toString(), 20).show();
Log.i("WebService output", response.toString());
System.out.println("WebService Response"+response.toString());
Object res= response.toString();
resultval=(String) res;
}
catch(Exception e){
e.printStackTrace();
}
return res;
}
protected void onPostExecute(String h){
String result=h;
tv.setText(result+"°F");
}
}
}
Just replace your service AsyncTask with this new one and see result:
code:
private class service extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... arg0) {
System.out.println("In DoIn Background");
// Initialize soap request + add parameters
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// Use this to add parameters
request.addProperty("Celsius", txtCel.getText().toString());
// Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try {
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
// this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION, envelope);
// Get the SoapResult from the envelope body.
SoapObject result = (SoapObject) envelope.bodyIn;
if (result != null) {
// Get the first property and change the label text
// txtFar.setText(result.getProperty(0).toString());
res = result.getProperty(0).toString();
} else {
Toast.makeText(getApplicationContext(), "No Response",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
protected void onPostExecute(String h) {
String result = h;
tv.setText(result + "°F");
}
}

Categories

Resources