I'm coding an app that primarily uses data gotten from a web service, and I want to use AsyncTask to run the SOAP calls in the background... I'm fairly new to Android(being an iOS programmer), so I'm a bit new at this...
Now, I have a login screen, where I take a user-provided login and check it against information on a server...
So in my login activity:
loginBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
//Run the connection to authenticate the user
AuthenticateConnection mAuth = new AuthenticateConnection();
mAuth.mNumber = number;
mAuth.mPassword = pass;
mAuth.connection();
}
}
and my soap class is this:
public class AuthenticateConnection
{
private static final String SOAP_ACTION = "http://tempuri.org/Authenticate";
private static final String METHOD_NAME = "Authenticate";
private static final String NAMESPACE = "http://tempuri.org/";
private String URL;
public Boolean userOK;
public String mNumber;
public String mPassword;
public AuthenticateConnection()
{
}
public void connection()
{
Singleton service = Singleton.getInstance();
String firstURL = service.getURL();
URL = firstURL + "Parent.svc";
System.out.println("Connection to: " + URL);
//Initialize soap request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//Add parameters
request.addProperty("login", mNumber);
request.addProperty("password", mPassword);
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.implicitTypes=true;
envelope.setAddAdornments(false);
//Prepare request
envelope.setOutputSoapObject(request);
//Needed to make the internet call
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//Allow for debugging - needed to output the request
androidHttpTransport.debug = true;
try
{
//this is the actual part that will call the web service
androidHttpTransport.call(SOAP_ACTION, envelope);
//Get the SoapResult from the envelope body.
//Object result = envelope.getResponse();
//Object result = envelope.bodyIn;
SoapObject sResult = (SoapObject)envelope.bodyIn;
String tempID = sResult.getProperty("AuthenticateResult").toString();
//Check if the user exists and has the correct password
if(tempID != "-1")
{
userOK = true;
//Store the values in the singleton class
service.parentID = sResult.getProperty("AuthenticateResult").toString();
service.parentToken = sResult.getProperty("token").toString();
}
//If -1 is returned, then either the number or the password is incorrect
else
{
userOK = false;
}
} catch(org.xmlpull.v1.XmlPullParserException ex2)
{
//System.out.println(androidHttpTransport.requestDump.toString());
} catch (Exception e)
{
e.printStackTrace();
System.out.println(androidHttpTransport.requestDump.toString());
}
}
}
So my question is, how would I do this with AsyncTask?
I've been looking at some tutorial on AsyncTask, but haven't really "gotten it" so far...
You can do:
private class ConnectionTask extends AsyncTask<String, Void, Void> {
private ProgressDialog dialog = new ProgressDialog(ACTIVITY_NAME.this);
protected void onPreExecute() {
dialog.setMessage("Connecting...");
dialog.show();
}
protected void doInBackground(String... args) {
AuthenticateConnection mAuth = new AuthenticateConnection();
mAuth.mNumber = args[0];
mAuth.mPassword = args[1];
mAuth.connection();
}
protected void onPostExecute(Void v) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
And then call it:
loginBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
//Run the connection to authenticate the user
new ConnectionTask().execute(number, pass);
}
}
Your connection method in AuthenticateConnection should return something to ensure the user has been authenticated. Then you can use that value in the onPostExecute, something like this:
protected void onPostExecute(Integer res) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (res.intValue() == OK) {
/* Maybe start a new Activity ...*/
} else {
/* Maybe show a Toast with an error message ...*/
}
}
In this case the signature of the asynctask will change:
private class ConnectionTask extends AsyncTask<String, Void, Integer>
and the doInBackground should return an Integer.
Hope it helps.
Related
Im trying to get some response from several SOAP webservices at last i tried to run a code that is a well very known example on the internet. But i realized that even this doesnt run on my project. I hardly tried to understand what the error could be but i dont know why its not working with soap.
I would really appriacate your help.
Downloaded new version of KSOAP2 and also permission for internet is given.
public class WEBSERVİCE extends AppCompatActivity {
Button btn;
EditText et;
TextView txv;
String celcius="21";
String fahren;
private String NAMESPACE = "https://www.w3schools.com/xml/";
private String METHOD_NAME = "CelsiusToFahrenheit";
private String SOAP_ACTİON = "https://www.w3schools.com/xml/CelsiusToFahrenheit";
private String URL = "https://www.w3schools.com/xml/tempconvert.asmx?op=CelsiusToFahrenheit?WSDL";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.button);
txv = findViewById(R.id.textView);
et = findViewById(R.id.editText1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AsyncCallWS task = new AsyncCallWS();
task.execute();
}
});
}
private class AsyncCallWS extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
txv.setText("calculating");
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected String doInBackground(String... objects) {
return getBolum(celcius);
}
#Override
protected void onPostExecute(String o) {
txv.setText(fahren + "F");
super.onPostExecute(o);
}
}
public String getBolum(String celsius) {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi = new PropertyInfo();
pi.setName("Celcius");
pi.setValue(celsius);
pi.setType(double.class);
request.addProperty(pi);
SoapSerializationEnvelope envelope = new
SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHTTPTransport = new HttpTransportSE(URL);
try {
androidHTTPTransport.call(SOAP_ACTİON, envelope);
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
fahren = response.toString();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return fahren;
}
}
No Error Messages but the value it turns back is always "null"
EDIT:posted changed code again
There isn't anything wrong with SOAP Api. The problem is your AsyncTask class. Read the documentation for AsyncTask first. Please do proper research before you use any code from internet. Always read about the components that are used snippets on internet otherwise you are going to have hard time figuring out problems.
Your AsyncTask class is declared as:
private class AsyncCallWS extends AsyncTask<String,Void,Void>
Change it to
private class AsyncCallWS extends AsyncTask<String,Void,String>
Third generic parameter in your Void which is supposed to be result type. So in your case your async task won't return any data once it is finished.
//CHANGE TYPE TO STRING
public String getBolum(String celsius) {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi=new PropertyInfo();
pi.setName("Celcius");
pi.setValue(celsius);
pi.setType(double.class);
request.addProperty(pi);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHTTPTransport = new HttpTransportSE(URL);
try {
androidHTTPTransport.call(SOAP_ACTİON, envelope);
SoapPrimitive response= (SoapPrimitive) envelope.getResponse();
//RETURN RESULT
return response.toString();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
//I forgot this line previously:
return "";
}}
In your async task, you need to change return type of doInBackground and paramter of onPostExecute to String:
#Override
protected String doInBackground(String... objects) {
return getBolum(celcius); //RETURN RESULT
}
#Override
protected void onPostExecute(String result) {
txv.setText(result+"F");
fahren = result;
super.onPostExecute(result);
}
It should work now.
What i have is an asynctask that i use it to send data to web service which work just fine , and here is my web service code :
public class WebServiceDetails {
//Namespace of the Webservice - can be found in WSDL
private static String NAMESPACE = "http://tempuri.org/";
//Webservice URL - WSDL File location
//URL = "http://80.90.161.246:70/erP_Reporting/OrderAndroid.asmx";
private static String URL = "http://192.168.1.124/alibabanewwebservice/AliBabaWebService.asmx";//Make sure you changed IP address
//private static String URL = "http://192.168.1.103/webservicejal6ah/OrderAndroid.asmx";//Make sure you changed IP address
//SOAP Action URI again Namespace + Web method name
private static String SOAP_ACTION = "http://tempuri.org/InsertOrderDetails";
public static boolean invokeLoginWS(String DeviceId, String Item_id, String Item_Quantity,String Bounce,String webMethName)
{
boolean loginStatus = false;
// Create request
SoapObject request = new SoapObject(NAMESPACE, webMethName);
// Property which holds input parameters
PropertyInfo deviceid = new PropertyInfo();
PropertyInfo itemid = new PropertyInfo();
PropertyInfo quantity = new PropertyInfo();
PropertyInfo bounce= new PropertyInfo();
deviceid.setName("DeviceId");
deviceid.setValue(DeviceId);
deviceid.setType(String.class);
request.addProperty(deviceid);
itemid.setName("Item_id");
itemid.setValue(Item_id);
itemid.setType(String.class);
request.addProperty(itemid);
quantity.setName("Item_Quantity");
quantity.setValue(Item_Quantity);
quantity.setType(String.class);
request.addProperty(quantity);
bounce.setName("Bounce");
bounce.setValue(Bounce);
bounce.setType(String.class);
request.addProperty(bounce);
// extra.setName("Extra");
// extra.setValue(Extra);
// extra.setType(String.class);
// request.addProperty(extra);
// Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(1);
envelope.dotNet = true;
// Set output SOAP object
envelope.setOutputSoapObject(request);
// Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
// Invoke web service
androidHttpTransport.call(SOAP_ACTION, envelope);
// Get the response
// SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
Object response = (Object) envelope.getResponse();
// Assign it to boolean variable variable
loginStatus = Boolean.parseBoolean(response.toString());
} catch (Exception e) {
//Assign Error Status true in static variable 'errored'
e.printStackTrace();
}
//Return booleam to calling object
return loginStatus;
}
}
And here is my asynctask :
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.e("Customer_Name","sereen");
//Make Progress Bar invisible
//AddToCart.cartlist.clear();
try{
//Log.e(" Customer_Id=masterrs.get(m).getCustomerId()", rs.get(m).getCustomerId());
Toast.makeText(CartList.this, "order has been send ", Toast.LENGTH_LONG).show();
}
catch(Exception e){
e.printStackTrace();
}
}
//Make Progress Bar visible
protected void onPreExecute() {
super.onPreExecute();
pd.setTitle("sending");
pd.setMessage("waiting...");
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
loginStatus2 = WebServiceDetails.invokeLoginWS(Device_ID,Item_Id,Quantity,Bounce,"InsertOrderDetails");
Log.e("Device_ID details",Device_ID+"");
// try{
//Log.e(" Customer_Id=masterrs.get(m).getCustomerId()", rs.get(m).getCustomerId());
// }
// catch(Exception e){
// e.printStackTrace();
// }
//
// }
}
return null;
}
}
well , the problem is as you can see my asynctask return null value and i want it after i send value to return true for (loginStatus2) but the thing is when i tried to do it , it didn't work .. can anyone help me , what shall i change to get the value true when success post on web service and false when it fails?
Try this code for AsyncTask. Use result and check if it is null or not.
If null, there is no response else you can have response in form of result from Asynctask() method.
private class AsyncCallWS extends AsyncTask<Void, Void, String> {
String response;
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result==null){
Toast.makeText(CartList.this, "result is null", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(CartList.this, "Result is: "+ result, Toast.LENGTH_LONG).show();
}
try{ //Your code here
//Log.e(" Customer_Id=masterrs.get(m).getCustomerId()", rs.get(m).getCustomerId());
Toast.makeText(CartList.this, "order has been send ", Toast.LENGTH_LONG).show();
}
catch(Exception e){
e.printStackTrace();
}
}
//Make Progress Bar visible
protected void onPreExecute() {
super.onPreExecute();
pd.setTitle("sending");
pd.setMessage("waiting...");
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
loginStatus2 = WebServiceDetails.invokeLoginWS(Device_ID,Item_Id,Quantity,Bounce,"InsertOrderDetails");
response = loginStatus2;
Log.e("Device_ID details",Device_ID+"");
}
return response;
}
}
Tried using Async but got can't handler even there is no toast in it,
also tried call calling method runUIThread but no luck ,
Async method works but it also gets run time exception
when i use Async method data gets on the Textview too late (5-10 mins) , but when i use it in debuggers it gets instantly ,
below webservice is test using wizdl application and response is instant
i'm confused please help
private final String NAMESPACE = "http://????????.com/EventGetter/";
private final String URL = "http://?????????.com/EventGetter.asmx";
private final String SOAP_ACTION = "http://????????.com/EventGetter/GetTimeTable";
private final String METHOD_NAME = "GetTimeTable";
private class TPaccessData extends AsyncTask<String, Void, Void>{
#Override
protected Void doInBackground(String... params) {
GetData();
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(LogStr, "onPostExecute");
}
#Override
protected void onPreExecute() {
GetData();
Log.i(LogStr, "onPreExecute");
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i(LogStr, "onProgressUpdate");
}
}
public void GetData(){
//Create request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//set properties aka param
request.addProperty("stream","where ttBatch = 'F.Y.J.C'");
//Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
//Set output SOAP object
envelope.setOutputSoapObject(request);
//Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.debug = true;
//Invole web service
androidHttpTransport.call(SOAP_ACTION, envelope);
//Get the response
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
//Assign it to Text static variable
text.setText(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
also tried calling get data in oncreate method
NotifyList.this.runOnUiThread(new Runnable() {
#Override
public void run() {
GetData();
// TPaccessData task = new TPaccessData();
// task.execute();
}
});
Remove youe GetData() method from onPreExecute()
and call this line inside onPost
text.setText(response.toString());
I'm implementing an AsyncTask, that calls a WCF service methods in the doInBackground method.
the WCF method name is a parameter for the doInBackground method.
I want the progress dialog to show only for specific methods name sent to doInBackground.
My porgressdialog setting are set in onPreExecute methods.
Any way to make progressdialog appear for a specific doInBackground parameter (wcf method name)
public class WCFHelper extends AsyncTask<Object, Void, String[]>{
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://url";
final ProgressDialog pd;
public Context ctx;
public WCFHelper(Context _ctx)
{ this.ctx = _ctx;
pd = new ProgressDialog(_ctx);
}
#Override
protected void onPreExecute() {
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("login...");
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
}
#Override
protected String[] doInBackground(Object... params) {
String WCFmethod = (String)params[0];
Map<String,Object> parameterArgs = (Map<String,Object>)params[1];
Boolean isArr = (Boolean)params[2];
String [] Fail = {"Fail"};
String SOAP_ACTION = "http://tempuri.org/IService1/"+WCFmethod;
String METHOD_NAME = WCFmethod;
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
for(Map.Entry<String,Object> entry: parameterArgs.entrySet())
request.addProperty(entry.getKey().toString(), entry.getValue().toString());
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
if(!isArr)
{
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
String[] toReturn = new String[1];
toReturn[0] = result.toString();
return toReturn;
}
else{
envelope.implicitTypes = true ;
SoapObject listDataSet = (SoapObject) envelope.bodyIn;
int numOfStrings = ((SoapObject)listDataSet.getProperty(0)).getPropertyCount();
String[] toReturn = new String[numOfStrings];
for ( int i = 0 ; i <numOfStrings; i++) {
toReturn[i] = ((SoapObject)listDataSet.getProperty(0)).getProperty(i).toString();
}
return toReturn;
}
}
catch (Exception e) {
return Fail;
}
}
protected void onPostExecute(String res) {
// TODO: check this.exception
// TODO: do something with the feed
if(this.pd.isShowing())
pd.dismiss();
}
As you can see one of the params for doInBackground is WCF method name.
I want the progressdialog to show only to specific WCF methods (received as parameter)
Send parameters also during instantiating the WCHelper object.
Keep a variable in the WCFHelper class.
public class WCFHelper extends AsyncTask<Object, Void, String[]>{
int val;
public WCHelper(int param) //constructor
{
super();
val = param; //now you can use this val in onPreExecute
}
...
}
Send the same parameter you wanted to send to onPreExecute(). For example,
WCHelper task = new WCHelper(param); // this sends value to constructor
task.execute(param); //this sends value to doInBackground
You can create your own custom constructor of the AsyncTask to transfer necessary parameter for handling the progress dialog.
private class MyTask extends AsyncTask<Void, Void, Void> {
public MyTask(boolean showProgress){
....
}
....
}
I want to use a SOAP-based web service in Android, but I don't know the concept of how to use SOAP-based web services. I previously have done XML parsing for simple XML web services, but don't know about SOAP-based ones. Can you tell me how to use SOAP-based web services in Android...
Try this, This code is for login-user using Ksoap
public class Login extends Activity {
/** Called when the activity is first created. */
private static final String SOAP_ACTION = "http://tempuri.org/LoginUser";
private static final String METHOD_NAME = "LoginUser";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://"
private static final String TAG = "HELLO"
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button signin = (Button) findViewById(R.id.regsubmitbtn);
signin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new StartLoginAsyncTask(yourclass.this).execute();
}
});
}
private class LoginTask extends AsyncTask<Void, Void, Boolean> {
private final ProgressDialog dialog =
new ProgressDialog(YourClass.this);
protected void onPreExecute() {
this.dialog.setMessage("Logging in.........");
this.dialog.show();
}
protected Boolean doInBackground(final Void unused) {
return Main.this.login(); //don't interact with the ui!
}
protected void onPostExecute(final Boolean result) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
if (result.booleanValue()) {
//also show register success dialog
}
}
}
private String doLogin() {
EditText etxt_user = (EditText)findViewById(R.id.emaileditlog);
String email_id = etxt_user.getText().toString();
EditText etxt_password = (EditText)findViewById(R.id.pwdeditlog);
String password = etxt_password.getText().toString();
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("email", email);
request.addProperty("password", password);
SoapSerializationEnvelope soapEnvelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(request);
HttpTransportSE aht = new HttpTransportSE(URL);
Pattern EMAIL_ADDRESS_PATTERN =
Pattern.compile("[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
"\\#" +
"[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
"(" +
"\\." +
"[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
")+");
Matcher matcher = EMAIL_ADDRESS_PATTERN.matcher(email_id);
if (matcher.matches()) {
Log.v(TAG, "Your email id is valid ="+email_id);
// System.out.println("Your email id is valid ="+email);
} else {
// System.out.println("enter valid email id");
Log.v(TAG, "enter valid email id" );
}
if (password != null) {
if (email_id.equalsIgnoreCase("") || password.equalsIgnoreCase("")) {
System.out.println("Fields should not be EMPTY");
}
}
SoapObject request = new SoapObject(NAMESPACE_LOGIN, METHOD_NAME_LOGIN);
request.addProperty("email", email_id);
request.addProperty("pwd", password);
SoapSerializationEnvelope soapEnvelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(request);
HttpTransportSE aht = new HttpTransportSE(URL_LOGIN);
try {
aht.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
aht.call(SOAP_ACTION_LOGIN, soapEnvelope);
SoapObject resultsRequestSOAP = (SoapObject) soapEnvelope.bodyIn;
Log.v("TAG", String.valueOf(resultsRequestSOAP));
Object response=(Object)soapEnvelope.getResponse();
temp=response.toString();
} catch (Exception e) {
e.printStackTrace();
}
return temp;
}
}
You should download and try out ksoap2 for Android.
You must do a thorugh research before asking a question. It is a simple problem which can be solved using google.
Anway, use these links
http://tknight.org/sdn/show/23160
http://www.android10.org/index.php/articleslibraries/167-using-ksoap2-for-android-soap-web-service
http://android.amberfog.com/?p=45
Also, use ksoap2 library from http://code.google.com/p/ksoap2-android/source/browse/m2-repo/com/google/code/ksoap2-android/ksoap2-android-assembly/2.5.7/ksoap2-android-assembly-2.5.7-jar-with-dependencies.jar. Click on view raw file to download the jar