370 likes | 538 Views
Android 智慧型手機程式設計. Android WebService. 建國科技大學 資管系 饒瑞佶 2012/4 V1 2012/8 V2 2013/5 V3. 提醒 …. 這節的內容針對的是 MS 的 Web Service 或是使用 SOAP(Simple Object Access Protocol) 標準建立的 Web Service 針對其它資料庫或是 data provider ,建議可以採用 HTTPPost 或是 HttpGet. Why Web Service?. 資訊 / 功能分享 標準 (SOAP 、 XML 、 JSON) 安全
E N D
Android智慧型手機程式設計 AndroidWebService 建國科技大學 資管系 饒瑞佶 2012/4 V1 2012/8 V2 2013/5 V3
提醒… • 這節的內容針對的是MS的Web Service或是使用SOAP(Simple Object Access Protocol)標準建立的Web Service • 針對其它資料庫或是data provider,建議可以採用HTTPPost或是HttpGet
Why Web Service? • 資訊/功能分享 • 標準(SOAP、XML、JSON) • 安全 • 其他…
WebService • 需要ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar或ksoap2-android-assembly-2.5.2-jar-with-dependencies_timeout1.jar • ProjectPropertiesJava Build PathLibraries Add External JARs • 需要設定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
幾個重點 • 沒有參數的WebService • 有參數的WebService • DNS問題
WebService • 現有可以被呼叫的WebService: • 攝氏與華氏轉換 • http://www.w3schools.com/webservices/tempconvert.asmx • 取得國家 • http://www.webserviceX.NET/country.asmx
WebService • Step1:建立新專案HelloWS • Step2:main.xml中建立一個輸入框(EditText)、兩個TextView與一個按鈕(Button) EditText TextView TextView Button
WebService • Step3:加入ksoap2這個外部jar • Step4:宣告webservice參數 //有參數值的Web Service ---攝氏與華氏轉換(AVD無法解析domain name) private static final String NAMESPACE = "http://tempuri.org/" ; 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://tempuri.org/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 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; } • Step6:撰寫webservice主體
呼叫tempconvert btn_ok.setOnClickListener(new Button.OnClickListener() { publicvoid 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
My Suggestion • 試試另一個取得國家代號的webservice • 選用只能輸入數字的EditText • 加入等待訊息或進度畫面 • 將結果帶到下一個Activity做顯示 • 回傳結果不只一筆,分割資料後,再用ListActivity做顯示 • 將結果存入SQLite • …
整合ListView • 無參數 • 回傳一組以,為分隔符號的結果 privatestaticfinal String NAMESPACE = "http://tempuri.org/" ; privatestaticfinal String URL = "http://211.20.52.86/map_ap_1/city.asmx"; privatestaticfinal String METHOD_NAME = "city"; privatestaticfinal String SOAP_ACTION = "http://tempuri.org/city";
整合ListView 呼叫Web Service ListView
code @Override publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String getbackcity=WScity(); //呼叫WS String [] cities= getbackcity.split(","); //利用,切割取得的字串變陣列 //設定利用ListView顯示 setListAdapter(newArrayAdapter <String>(this,android.R.layout.simple_list_item_checked,cities)); getListView().setTextFilterEnabled(true); //設定可以篩選 // 取得listview ListView lv=this.getListView(); lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); //設定可勾選 //lv.setFilterText("台"); }
code public String WScity(){ String receivedString="nok"; //預設回傳值 try { SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 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="nok"; return receivedString; } return receivedString; }
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請求 } 加入!
整合Spinner • WebService呼叫不變 要加一個有Spinner的layout Spinner
Spinner sp=(Spinner)findViewById(R.id.spinner1); String getbackcity=WScity(); //呼叫WS String [] cities= getbackcity.split(","); //利用,切割取得的字串變陣列 //設定利用Spinner顯示 ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainSpinner.this,android.R.layout.simple_spinner_item,cities ); //設定下拉選單的樣式 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); sp.setAdapter(adapter);
private ProgressDialog MyDialog=null; createCancelProgressDialog("擷取中","請稍待...","取消"); @SuppressWarnings("deprecation") privatevoidcreateCancelProgressDialog(String title, String message, String buttonText) { MyDialog = newProgressDialog(this); MyDialog.setTitle(title); MyDialog.setMessage(message); MyDialog.setButton(buttonText, newDialogInterface.OnClickListener(){ publicvoidonClick(DialogInterface dialog, int which){ // Use either finish() or return() to either close the activity or just the dialog MyDialog.dismiss(); return; } }); MyDialog.show(); }
有沒有興趣看看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%85%8B%E6%96%B0%E5%A2%9Etextview%E8%87%B3tablela