Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 調用webservice(ksoap-2-Android)手機號碼歸屬地查詢

Android 調用webservice(ksoap-2-Android)手機號碼歸屬地查詢

編輯:關於Android編程

之前做過一次但是隔了一個月再做就有點忘了,果然好記性不如爛筆頭!還是打算記一下。

現在網絡上的一些有關這方面的文章都比較久遠了雖然方法沒錯但是之前的網址都變了所以需要進行一些修改。


知識點概述

1. soap

soap一般跟web服務一起講。通俗地講,web服務就是將網絡上的message消息作為輸入然後再從網絡上得到輸出的過程。【需要注意的是,web服務並不僅僅指的是我們平常所用的網站,它包括一切可以由web訪問到的服務。】
為了實現web服務的協同需要實現message交換和遠程程序的調用,即基於XML進行的RPC(Remote Procedure Call),這個過程就是SOAP(Simple Object Access Protocol,簡單對象訪問協議)——網絡對象之間進行情報交換的單純的輕量級的協議。
soap協議的內容 詳細請看這裡 [翻譯]Speaking SOAP with Android——談一談android的soap通信 這是我之前看了一個外國小哥寫的有關於soap和ksoap2的文章的翻譯,覺得對於初學者來說很有幫助,換句話說就是有助於入門。覺得看翻譯太煩的,我還是在這裡進行簡單的總結:

SOAP封裝-Envelope:它定義了一個框架,描述消息中的內容是什麼,是誰發送的,誰應當接受並處理它以及如何處理它們; SOAP編碼規則-Encoding Rules:它定義了一種序列化機制,用於表示應用程序需要使用的數據類型的實例; SOAP RPC表示-RPC Representation:它定了一個協定,用於表示遠程過程調用和應答;

SOAP綁定-Binding:它定義了SOAP使用哪種協議交換信息。使用HTTP/TCP/UDP協議都可以

SOAP消息基本上是從發送端到接收端的單向傳輸,但它們常常結合起來執行類似於請求 / 應答的模式。所有的 SOAP消息都使用 XML 編碼。一條 SOAP消息就是一個包含有一個必需的 SOAP 的封裝包,一個可選的 SOAP 標頭head和一個必需的 SOAP 主體body的 XML 文檔。

2.android中的soap協議

目前的開發平台並不支持內嵌的soap協議的開發,在Android平台調用Web Service需要依賴於第三方類庫ksoap2,它是一個SOAP Web service客戶端開發包,主要用於資源受限制的Java環境如Applets或J2ME應用程序(CLDC/ CDC/MIDP)。所以如果你想要開發有soap通信的Android程序需要外部導入soap協議的包。

3.wsdl

WSDL:Web Services Description Language的縮寫,是一個用來描述Web服務和說明如何與Web服務通信的XML語言。為用戶提供詳細的接口說明書。


ksoap-2-android使用

1.在使用之前你需要下載ksoap-a-android 2.4.5.jar包,下載地址:http://www.webservicex.net/CurrencyConvertor.asmxwebservice
2.需要一個wsdl文檔來進行測驗,我們將手機號碼歸屬地查詢的地址作為測試例子http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx 只是用裡面其中一個方法getMobileCodeInfo


下載並將外部jar包加入工程:具體過程查看-> Android Studio 導入第三方庫——*.jar包
在使用ksoap2之前我們需要會讀懂wsdl文檔,意思就是能夠從wsdl文檔中找到soapAction、namespaceAddress等信息。我們打開手機號碼歸屬地查詢的wsdl文檔 http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL

函數名  getMobileCodeInfo
參數列表 
    mobileCode = 字符串(手機號碼,最少前7位數字)
    userID = 字符串(商業用戶ID) 免費用戶為空字符串
返回值
    字符串(手機號碼:省份 城市 手機卡類型)

1.首先實例化一個SoapObject對象

SoapObject soapObject=new SoapObject(namespaceAddress,methodName);

參數:
namespaceAddress 在wsdl文檔裡阿敏可以找到targetnamesapce
methodName 就是函數名字
2.添加函數的參數

soapObject.addProperty("mobileCode",num);
soapObject.addProperty("userID", "");

參數名字需要跟wsdl文檔中的名稱和順序一致
3.封裝

//生成調用WebService方法的SOAP請求信息,並指定SOAP的版本  
 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
  envelope.bodyOut = soapObject;
 // 設置是否調用的是dotNet開發的WebService  
  envelope.dotNet = true;
  // 等價於envelope.bodyOut = soapObject;
  envelope.setOutputSoapObject(soapObject);

SoapEnvelope.VER11表示協議版本,可以試一下11,12和10
4.調用webservice
urlAddress或者叫做Endpoint是包含asmx的地址

 HttpTransportSE httpTransportSE = new HttpTransportSE(urlAddress);
        try {
        //call函數參數soapAction在wsdl文檔中可以看到
        //這個操作會產生異常需要對異常進行處理
            httpTransportSE.call(soapAction,envelope);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }

5.獲得返回信息並取得結果

SoapObject object = (SoapObject) envelope.bodyIn;
String info=object.getProperty(0).toString();

取得的是一個xml結果,但是在第一句話轉換成SoapObject對象直接然後用getProperty函數直接取得結果,轉成字符串。

下面是wsdl文檔中關於函數getMobileCodeInfo的參數格式和返回格式



    
        
            
            
        
    


    
        
            
        
    

下面是soap1.1格式下的請求和響應
這裡寫圖片描述

實例

1.界面
這裡寫圖片描述
輸入框:EditText id=edtNum
按 鈕:Button id=btnok
顯示框:TextView id=tvInfo
輸入框背景:


    
    
    
    

2.實現

public class MainActivity extends AppCompatActivity {

    private static final String namespaceAddress="http://WebXml.com.cn/";
    private static final String urlAddress="http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx";
    private static final String methodName="getMobileCodeInfo";
    private static final String soapAction="http://WebXml.com.cn/getMobileCodeInfo";
    EditText edtNum;
    Button btnok;
    TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //設置在主線程裡直接運行子線程,下面主線程內不能用new thread
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectDiskReads().detectDiskWrites().detectNetwork()
                .penaltyLog().build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
                .penaltyLog().penaltyDeath().build());
        /**
         * edtNum號碼輸入框
         * tv 歸屬地查詢結果顯式TextView
         * btnok 點擊查詢按鈕
         */
        edtNum=(EditText)findViewById(R.id.edtNum);
        tv=(TextView)findViewById(R.id.tvInfo);
        btnok=(Button)findViewById(R.id.btnok);
        btnok.setOnClickListener(myListener);
    }

    /**
     * getTelInfo函數用於查詢手機號碼歸屬地並顯示在文本框內
     * @param num String 類型的手機號碼,長度不能少於7位數
     */
    public void getTelInfo(String num)
    {
        SoapObject soapObject=new SoapObject(namespaceAddress,methodName);
        //soapObject添加參數的順序必須與asmx裡面的參數順序一致,名稱保持一致
        soapObject.addProperty("mobileCode",num);
        soapObject.addProperty("userID", "");
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.bodyOut = soapObject;
        envelope.dotNet = true;
        envelope.setOutputSoapObject(soapObject);
        HttpTransportSE httpTransportSE = new HttpTransportSE(urlAddress);
        try {
            httpTransportSE.call(soapAction,envelope);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
        SoapObject object = (SoapObject) envelope.bodyIn;
        String info=object.getProperty(0).toString();
        tv.setText(info);
    }
    Button.OnClickListener myListener=new Button.OnClickListener()
    {
        @Override
        public void onClick(View v) {
            final String number=edtNum.getText().toString().trim();
            if(number.equals("")){
                Toast.makeText(getApplicationContext(),"號碼不能為空!",Toast.LENGTH_SHORT)
                        .show();
            }else if(number.length()<7||number.length()>11) {
                Toast.makeText(getApplicationContext(),"號碼格式不對,無法獲取信息!",Toast.LENGTH_SHORT)
                        .show();
            }
            else {
                getTelInfo(number);
            }
        }
    };
}

注意1:打開應用的網絡訪問權限——修改Manifest.xml
在application外層上面或者下面寫上下面這句權限:

注意2:主線程中不能直接訪問網絡的線程可以用新建線程的進行訪問。
最暴力的方法就是在主線程中加入:

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectDiskReads().detectDiskWrites().detectNetwork()
                .penaltyLog().build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
                .penaltyLog().penaltyDeath().build());
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved