Android 智 慧 型 手 機 程 式 設 計 Android WebService 建 國 科 技 大 學 資 管 系 饒 瑞 佶 2012/4 V1 2012/8 V2 2013/5 V3 2014/10 v4
提 醒 這 節 的 內 容 針 對 的 是 MS 的 Web Service 或 是 使 用 SOAP(Simple Object Access Protocol) 標 準 建 立 的 Web Service 針 對 其 它 資 料 庫 或 是 data provider, 建 議 可 以 採 用 HTTPPost 或 是 HttpGet
Why Web Service? 資 訊 / 功 能 分 享 標 準 (SOAP XML JSON) 安 全 其 他
WebService 透 過 外 部 jar 檔 案 需 要 ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar 或 ksoap2-android-assembly-2.5.2-jar-withdependencies_timeout1.jar Project Properties Java Build Path Libraries Add External JARs 目 前 最 新 版 本 是 3.3 https://code.google.com/p/ksoap2-android/source/browse/m2- repo/com/google/code/ksoap2-android/ksoap2-androidassembly/
幾 個 重 點 沒 有 參 數 的 WebService 有 參 數 的 WebService DNS 問 題
WebService 現 有 可 以 被 呼 叫 的 WebService: 攝 氏 與 華 氏 轉 換 http://www.w3schools.com/webservices/te mpconvert.asmx 取 得 國 家 http://www.webservicex.net/country.asmx
攝 氏 與 華 氏 轉 換
WebService Step1: 建 立 新 專 案 HelloWS Step2:main.xml 中 建 立 一 個 輸 入 框 (EditText) 兩 個 TextView 與 一 個 按 鈕 (Button) TextView EditText TextView Button
WebService Step3: 加 入 ksoap2 這 個 外 部 jar Step4: 宣 告 webservice 參 數 // 有 參 數 值 的 Web Service --- 攝 氏 與 華 氏 轉 換 (AVD 無 法 解 析 domain name) private static final String NAMESPACE = "http://www.w3schools.com/webservices/" ; private static final String URL="http://www.w3schools.com/webservices/tempconvert.asmx"; private static final String METHOD_NAME = "CelsiusToFahrenheit"; private static final String SOAP_ACTION = "http://www.w3schools.com/webservices/celsiustofahrenheit"; private EditText et_pramater; // 輸 入 框 private Button btn_ok; // 按 鈕 private TextView tv_msg; // 訊 息 框
WebService Step5: 建 立 物 件 et_pramater =(EditText) findviewbyid(r.id.edittext1); btn_ok =(Button) findviewbyid(r.id.button1); tv_msg =(TextView) findviewbyid(r.id.textview2);
webservice 主 體 相 對 位 置
WebService Step6: 撰 寫 webservice 主 體 public String tempconvert(string temp){ String receivedstring="not work"; // 預 設 回 傳 值 try { SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); request.addproperty("celsius", temp); // 傳 入 溫 度 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setoutputsoapobject(request); envelope.dotnet = true; HttpTransportSE androidhttptransport = new HttpTransportSE(URL); androidhttptransport.call(soap_action, envelope); SoapPrimitive Result = (SoapPrimitive)envelope.getResponse(); receivedstring=result.tostring(); }catch(exception e) { receivedstring="not work"; return receivedstring; } return receivedstring; }
呼 叫 tempconvert
呼 叫 tempconvert btn_ok.setonclicklistener(new Button.OnClickListener() { public void onclick(view v) { String to_be_transfered; to_be_transfered=et_pramater.gettext().tostring(); String value_return; } }); if(to_be_transfered==null "".equals(to_be_transfered)){ tv_msg.settext(" 您 沒 有 輸 入 轉 換 值 "); et_pramater.setfocusable(true); // 輸 入 框 取 得 焦 點 }else{ value_return=tempconvert(to_be_transfered); // 呼 叫 WS if(value_return=="not work"){ tv_msg.settext(" 轉 換 失 敗 "); }else{ tv_msg.settext(value_return); } }
相 對 位 置
執 行 結 果
執 行 結 果
錯 誤 原 因 要 開 放 網 路 存 取 權 限 (Manifest.xml) <uses-permission android:name="android.permission.internet"></ uses-permission> 要 設 定 模 擬 器 的 DNS 允 許 使 用 jar
設 定 AVD 的 DNS AVD 需 要 設 定 DNS 才 可 以 連 結 有 Domain Name 的 WebService dns 解 決 方 法 adb shell #getprop 查 看 DNS 設 定 [net.dns1]: [192.168.2.1] net.dns1 就 是 目 前 的 設 定 setprop net.dns1 168.95.1.1 設 定 成 可 以 用 的 DNS
設 定 模 擬 器 DNS
執 行 結 果
執 行 結 果 驗 證
Android 4.x 以 後 需 要 改 成 非 同 步 呼 叫 加 入 非 同 步 class private class AsyncCallWS extends AsyncTask<String, Void, Void> { @Override protected Void doinbackground(string... params) { tempconvert(to_be_transfered); // 呼 叫 WS return null; } @Override protected void onpostexecute(void result) { tv_msg.settext(receivedstring + F ); } // 執 行 doinbackground 後 執 行 @Override protected void onpreexecute() { tv_msg.settext( Calculating... ); // 執 行 doinbackground 前 執 行 } @Override protected void onprogressupdate(void... values) { } }
改 成 非 同 步 呼 叫 btn_ok.setonclicklistener(new Button.OnClickListener() { public void onclick(view v) { to_be_transfered=et_pramater.gettext().tostring(); String value_return; if(to_be_transfered==null "".equals(to_be_transfered)){ tv_msg.settext(" 您 沒 有 輸 入 轉 換 值 "); et_pramater.setfocusable(true); // 輸 入 框 取 得 焦 點 }else{ AsyncCallWS task = new AsyncCallWS(); task.execute(); } } });
如 果 還 有 網 路 問 題 android.os.networkonmainthreadexception 在 Android 3.0 版 本 之 後 對 網 路 存 取 增 加 了 一 些 限 制 不 能 在 oncreate() 方 法 中 直 接 使 用 外 部 連 結
解 決 方 法 @Override public void oncreate(bundle savedinstancestate) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork() // or.detectall() for all detectable problems.penaltylog().build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath().build()); 加 入! super.oncreate(savedinstancestate);... } // 發 送 Http 請 求
加 入!
要 連 結 其 他 資 料 庫 或 API 服 務 呢? 可 考 慮 HTTPPost 或 HTTPGet http://seanstar5317.pixnet.net/blog/post/28092031- %5Bandroid%5D%E5%BE%9Emysql- %E6%8A%93%E8%B3%87%E6%96%99%EF%BC%8C%E5%8B%95%E6%8 5%8B%E6%96%B0%E5%A2%9Etextview%E8%87%B3tablela