如何从 Android 移动应用程序调用本地 Web 服务

Posted

技术标签:

【中文标题】如何从 Android 移动应用程序调用本地 Web 服务【英文标题】:How to call a local web service from an Android mobile application 【发布时间】:2011-12-13 05:42:12 【问题描述】:

从过去几天开始,我一直在编写一个调用本地 Web 服务的 android 代码。我正在使用 Android 的 ksoap 库来调用我在 .NET 中创建的 SOAP Web 服务。但是,我觉得我的代码有问题,因为当我从我的应用程序调用 Web 服务时得到的响应遇到了 catch 块。我尝试调试我的 Android 代码,但我仍然无法解决我的问题。 请有人告诉我有什么问题或其他更简单的方法吗?

这是我迄今为止实现的 Android 代码:

      package com.demo;
      import java.net.SocketException;
      import org.ksoap2.SoapEnvelope;
      import org.ksoap2.serialization.SoapObject;
      import org.ksoap2.serialization.SoapPrimitive;
      import org.ksoap2.serialization.SoapSerializationEnvelope;
      import org.ksoap2.transport.AndroidHttpTransport;
      import android.app.Activity;
      import android.app.ProgressDialog;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.View;
      import android.view.View.OnClickListener;
      import android.widget.Button;
      import android.widget.EditText;

    public class Login extends Activity 
private static final String SOAP_ACTION = "http://tempuri.org/GetLoginDetails";
    private static final String METHOD_NAME = "GetLoginDetails";
    private static final String NAMESPACE = "http://tempuri.org/";
    private static final String URL = "http://10.0.2.2/testlogin/Service1.asmx";

@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) 


                        EditText etxt_user = (EditText) findViewById(R.id.usereditlog);
                        user_id = etxt_user.getText().toString();
                        EditText etxt_password = (EditText) findViewById(R.id.pwdeditlog);
                        password = etxt_password.getText().toString();

                        new LoginTask().execute();
                
        );


 String user_id;
String password;
String auth=null;
private class LoginTask extends AsyncTask<Void, Void, Void> 

    private final ProgressDialog dialog = new ProgressDialog(
                    Login.this);

    protected void onPreExecute() 
            this.dialog.setMessage("Logging in...");
            this.dialog.show();
    

    protected Void doInBackground(final Void... unused) 

             auth = doLogin("lalit", "lalit");
            return null; // don't interact with the ui!
    

    protected void onPostExecute(Void result) 
        if (this.dialog.isShowing()) 
            this.dialog.dismiss();
        

         


       private String doLogin(String user_id, String password) 

    SoapPrimitive resultstring = null;
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    request.addProperty("user", user_id);
    request.addProperty("password", password);
    SoapSerializationEnvelope soapenvelope = new SoapSerializationEnvelope(
                    SoapEnvelope.VER11);
    soapenvelope.dotNet = true;                                                      
    soapenvelope.setOutputSoapObject(request);

    AndroidHttpTransport httptransport = new AndroidHttpTransport(URL);
    httptransport.debug = true;

    try 
            httptransport.call(SOAP_ACTION, soapenvelope);
            resultstring = (SoapPrimitive) soapenvelope.getResponse();
            //Log.d("Authenticaion", resultstring+"");
            System.out.println(resultstring);


    
    catch (SocketException ex) 
        Log.e("Error : " , "Error on soapPrimitiveData() " + ex.getMessage());
        ex.printStackTrace();
     catch (Exception e) 
        Log.e("Error : " , "Error on soapPrimitiveData() " + e.getMessage());
       e.printStackTrace();
    
    return resultstring+"";

    
     
    

我的网络服务代码:

        using System;
        using System.Collections;
        using System.ComponentModel;
        using System.Data;
        using System.Linq;
        using System.Web;
        using System.Web.Services;
        using System.Web.Services.Protocols;
        using System.Xml.Linq;
        using System.Data.SqlClient;

     namespace LoginDetails
     
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
// [System.Web.Script.Services.ScriptService]
    public class Service1 : System.Web.Services.WebService
   


    [WebMethod]
  public String GetLoginDetails(string UserName, string Password)
    

   try
       
     using (SqlConnection myConnection = new SqlConnection(@"Data Source= .\SQLEXPRESS;Initial Catalog=student;User ID=sa;Password=demo"))
    
        myConnection.Open();

        using (SqlCommand myCommand = new SqlCommand())
        
            myCommand.Connection = myConnection;
            myCommand.CommandText = "SELECT COUNT(*) FROM Login WHERE UserName = @UserName AND Password = @Password";
            myCommand.Parameters.Add("@UserName", SqlDbType.VarChar).Value = UserName;
            myCommand.Parameters.Add("@Password", SqlDbType.VarChar).Value = Password;
            return (int)myCommand.ExecuteScalar() == 1 ? "success" : "bad username or password";
        
    

catch (Exception ex)
    
    Console.WriteLine(ex.Message);
    return "an error occurred.";
      

  

     


  

我的日志:

       10-22 21:49:17.635: DEBUG/dalvikvm(117): GC_EXTERNAL_ALLOC freed 901 objects /         

       10-22 21:49:18.015: WARN/KeyCharacterMap(117): No keyboard for id 0
       10-22 21:49:18.015: WARN/KeyCharacterMap(117): Using default keymap:  /system/usr/keychars/qwerty.kcm.bin
       10-22 21:49:22.275: INFO/ARMAssembler(58): generated s   scanline__00000077:03515104_00000000_00000000 [ 33 ipp] (47 ins) at [0x23df98:0x23e054] in 675711 ns
       10-22 21:49:42.025: INFO/System.out(274): an error occurred.
       10-22 21:49:42.045: WARN/InputManagerService(58): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@44eda178

【问题讨论】:

【参考方案1】:

使用 kSOAP2 可能具有挑战性……我知道。但它是一个很好的图书馆,我已经能够让它工作。我写过一些关于在 Android 上使用 kSOAP2 的文章。我讨论了通过网络传递简单和复杂的参数、接收数组以及使用 JDBC WebRowSet 对象。

http://roderickbarnes.com/blog/droid-chronicles-web-services-handling-complex-parameters

网站上还有其他关于使用 kSOAP2 的博客文章。我希望这会有所帮助。

【讨论】:

非常感谢您的回复!是的,我会尝试你的链接,让你知道它是否适合我! :-) 链接已过期!【参考方案2】:

不知何故,我设法解决了我的问题,我正在回答这个问题,以便它对将来看到这篇文章的人有用。

所以这里是修改后的代码:

             package com.demo;
             import java.net.SocketException;
             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.app.ProgressDialog;
             import android.os.AsyncTask;
             import android.os.Bundle;
             import android.util.Log;
             import android.view.View;
             import android.view.View.OnClickListener;
             import android.widget.Button;
             import android.widget.EditText;

     public class Login extends Activity 

  private final String NAMESPACE = "http://tempuri.org/";
  private final String URL = "http://10.0.2.2/testlogin/Service1.asmx";

    String user_id;
    String password;

  @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) 


                        EditText etxt_user = (EditText) findViewById(R.id.usereditlog);
                        user_id = etxt_user.getText().toString();
                        EditText etxt_password = (EditText)  findViewById(R.id.pwdeditlog);
                        password = etxt_password.getText().toString();

                        new LoginTask().execute();

                
           );   
     

    private boolean doLogin(String user_id, String password)    

   boolean result=false;
   final String SOAP_ACTION = "http://tempuri.org/GetLogin";
   final String METHOD_NAME = "GetLogin";     
   SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

   request.addProperty("userid", user_id);
   request.addProperty("password",password);
   SoapSerializationEnvelope envelope = new   SoapSerializationEnvelope(SoapEnvelope.VER11);
   envelope.dotNet = true; // Set this variable to true for
                                                           // compatibility with what seems to be the
                                                           // default encoding for .Net-Services.
   envelope.setOutputSoapObject(request);

   System.out.println(request);

   HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);


   try 
           androidHttpTransport.call(SOAP_ACTION, envelope);
           SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
           Log.i("myApp", response.toString());
           System.out.println("response" +response);

                   if(response.toString().equalsIgnoreCase("success"))
       
                   result = true;

       

   catch(SocketException ex)
   
       Log.e("Error : " , "Error on soapPrimitiveData() " + ex.getMessage());
       ex.printStackTrace();
   
   catch (Exception e) 
       Log.e("Error : " , "Error on soapPrimitiveData() " + e.getMessage());
           e.printStackTrace();
   
   return result;

   


private class LoginTask extends AsyncTask<Void, Void, Void> 

    private final ProgressDialog dialog = new ProgressDialog(
                    Login.this);

    protected void onPreExecute() 

            this.dialog.setMessage("Logging in...");
            this.dialog.show();

    


    protected Void doInBackground(final Void... unused) 

        boolean auth=doLogin(user_id,password);
        System.out.println(auth);

        return null;// don't interact with the ui!
    


    protected void onPostExecute(Void result) 


            if (this.dialog.isShowing()) 
            this.dialog.dismiss();
                 
      

     

    

【讨论】:

嘿,你上面的代码在 this.dialog.show() 中出现错误;和新的 LoginTask().execute();这两条线...我该如何解决

以上是关于如何从 Android 移动应用程序调用本地 Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

如何管理从本地移动应用程序调用 Play2!-Scala REST 服务发送的用户请求的身份验证/授权

Xamarin 移动应用开发指南 - 如何在 iOS、Android 和 UWP 的 WebView 中加载本地网站 (HTML/CSS/JS ..) [重复]

如何在 C# 桌面应用程序和移动(android)设备之间通过本地网络进行通信? [关闭]

如何将数据从服务器发送到Android?

Android - 应用更新后 WebView html5 本地存储不持久

使用 SSL 从设备上的 Ionic 应用程序调用本地开发服务器上的 API