天天看點

Android使用ksoap2調用C#中的webservice實作圖像上傳

   目錄:

   一. android使用ksoap2調用webservice

   二. 異步調用

   三. Android使用ksoap2調用C#中的webservice實作圖像上傳參考方法

   四. 圖像傳輸中Base64編碼問題

一. android使用ksoap2調用webservice

<a></a>

   android使用ksoap2調用webservice的基本代碼如下:

<code>package</code> <code>com.example.webserviceexample;</code>

<code>import</code> <code>java.io.IOException;</code>

<code>import</code> <code>org.ksoap2.SoapEnvelope;</code>

<code>import</code> <code>org.ksoap2.SoapFault;</code>

<code>import</code> <code>org.ksoap2.serialization.SoapObject;</code>

<code>import</code> <code>org.ksoap2.serialization.SoapPrimitive;</code>

<code>import</code> <code>org.ksoap2.serialization.SoapSerializationEnvelope;</code>

<code>import</code> <code>org.ksoap2.transport.HttpTransportSE;</code>

<code>import</code> <code>org.xmlpull.v1.XmlPullParserException;</code>

<code>import</code> <code>android.app.Activity;</code>

<code>import</code> <code>android.os.Bundle;</code>

<code>import</code> <code>android.view.Menu;</code>

<code>import</code> <code>android.view.View;</code>

<code>import</code> <code>android.view.View.OnClickListener;</code>

<code>import</code> <code>android.widget.Button;</code>

<code>import</code> <code>android.widget.EditText;</code>

<code>import</code> <code>android.widget.TextView;</code>

<code>public</code> <code>class</code> <code>MainActivity </code><code>extends</code> <code>Activity {</code>

<code>    </code><code>final</code> <code>static</code> <code>String NAMESPACE = </code><code>"http://tempuri.org/"</code><code>;</code>

<code>    </code><code>final</code> <code>static</code> <code>String METHOD_NAME = </code><code>"CelsiusToFahrenheit"</code><code>;</code>

<code>    </code><code>final</code> <code>static</code> <code>String SOAP_ACTION = </code><code>"http://tempuri.org/CelsiusToFahrenheit"</code><code>;</code>

<code>    </code><code>final</code> <code>static</code> <code>String URL = </code><code>"http://www.w3schools.com/webservices/tempconvert.asmx"</code><code>;</code>

<code>    </code><code>TextView sonuc;</code>

<code>    </code><code>EditText deger;</code>

<code>    </code><code>Button hesapla;</code>

<code>    </code><code>@Override</code>

<code>    </code><code>public</code> <code>void</code> <code>onCreate(Bundle savedInstanceState) {</code>

<code>        </code><code>super</code><code>.onCreate(savedInstanceState);</code>

<code>        </code><code>setContentView(R.layout.activity_main);</code>

<code>        </code><code>deger = (EditText) findViewById(R.id.deger);</code>

<code>        </code><code>sonuc = (TextView) findViewById(R.id.flag);</code>

<code>        </code><code>hesapla = (Button) findViewById(R.id.hesapla);</code>

<code>        </code><code>hesapla.setOnClickListener(</code><code>new</code> <code>OnClickListener() {</code>

<code>            </code><code>public</code> <code>void</code> <code>onClick(View v) {</code>

<code>                </code><code>//request info</code>

<code>                </code><code>SoapObject Request = </code><code>new</code> <code>SoapObject(NAMESPACE, METHOD_NAME);</code>

<code>                </code><code>Request.addProperty(</code><code>"Celcius"</code><code>,deger.getText().toString());</code>

<code>                </code><code>//envelope</code>

<code>                </code><code>SoapSerializationEnvelope soapEnvelope = </code><code>new</code> <code>SoapSerializationEnvelope(SoapEnvelope.VER11);</code>

<code>                </code><code>soapEnvelope.dotNet = </code><code>true</code><code>; </code><code>//.NET = true, php = false</code>

<code>                </code><code>//putting request to the envelope</code>

<code>                </code><code>soapEnvelope.setOutputSoapObject(Request);</code>

<code>                </code><code>//transferring data</code>

<code>                </code><code>HttpTransportSE aht = </code><code>new</code> <code>HttpTransportSE(URL); </code><code>//prepare</code>

<code>                </code><code>//start</code>

<code>                </code><code>try</code> <code>{</code>

<code>                        </code><code>aht.call(SOAP_ACTION, soapEnvelope);</code>

<code>                </code><code>}</code>

<code>                </code><code>catch</code> <code>(IOException e) {</code>

<code>                    </code><code>e.printStackTrace();</code>

<code>                </code><code>catch</code> <code>(XmlPullParserException e)</code>

<code>                </code><code>{</code>

<code>                </code><code>//waiting and getting response.</code>

<code>                </code><code>String result;</code>

<code>                    </code><code>// we are creating SoapPrimitive Object as waiting for simple variable.</code>

<code>                    </code><code>result = </code><code>"Fahrenheit:"</code> <code>+ soapEnvelope.getResponse();</code>

<code>                    </code><code>//writing the result to the textView</code>

<code>                    </code><code>sonuc.setText(result);</code>

<code>                </code><code>catch</code> <code>(SoapFault e) {</code>

<code>            </code><code>}</code>

<code>        </code><code>});</code>

<code>    </code><code>}</code>

<code>    </code><code>public</code> <code>boolean</code> <code>onCreateOptionsMenu(Menu menu) {</code>

<code>        </code><code>getMenuInflater().inflate(R.menu.activity_main, menu);</code>

<code>        </code><code>return</code> <code>true</code><code>;</code>

<code>}</code>

二. 異步調用

    上述代碼中,沒有異步調用,是不能正常執行的,會有如下警告:

<code>08-15 11:45:26.294: E/AndroidRuntime(641): FATAL EXCEPTION: main</code>

<code>08-15 11:45:26.294: E/AndroidRuntime(641): android.os.NetworkOnMainThreadException</code>

<code>import</code> <code>android.os.AsyncTask;</code>

<code>import</code> <code>android.util.Log;</code>

<code>    </code><code>private</code> <code>String TAG =</code><code>"Vik"</code><code>;</code>

<code>    </code><code>protected</code> <code>void</code> <code>onCreate(Bundle savedInstanceState) {</code>

<code>        </code><code>AsyncCallWS task = </code><code>new</code> <code>AsyncCallWS();</code>

<code>        </code><code>task.execute();</code>

<code>    </code><code>private</code> <code>class</code> <code>AsyncCallWS </code><code>extends</code> <code>AsyncTask&lt;Void, Void, Void&gt; {</code>

<code>        </code><code>@Override</code>

<code>        </code><code>protected</code> <code>Void doInVoid...  params) {</code>

<code>            </code><code>Log.i(TAG, </code><code>"doInBackground"</code><code>);</code>

<code>            </code><code>calculate();</code>

<code>            </code><code>return</code> <code>null</code><code>;</code>

<code>        </code><code>}</code>

<code>        </code><code>protected</code> <code>void</code> <code>onPostExecute(Void result) {</code>

<code>            </code><code>Log.i(TAG, </code><code>"onPostExecute"</code><code>);</code>

<code>        </code><code>protected</code> <code>void</code> <code>onPreExecute() {</code>

<code>            </code><code>Log.i(TAG, </code><code>"onPreExecute"</code><code>);</code>

<code>        </code><code>protected</code> <code>void</code> <code>onProgressUpdate(Void... values) {</code>

<code>            </code><code>Log.i(TAG, </code><code>"onProgressUpdate"</code><code>);</code>

<code>    </code><code>public</code> <code>void</code> <code>calculate()</code>

<code>    </code><code>{</code>

<code>        </code><code>String SOAP_ACTION = </code><code>"http://tempuri.org/CelsiusToFahrenheit"</code><code>;</code>

<code>        </code><code>String METHOD_NAME = </code><code>"CelsiusToFahrenheit"</code><code>;</code>

<code>        </code><code>String NAMESPACE = </code><code>"http://tempuri.org/"</code><code>;</code>

<code>        </code><code>String URL = </code><code>"http://www.w3schools.com/webservices/tempconvert.asmx"</code><code>;</code>

<code>        </code><code>try</code> <code>{</code>

<code>            </code><code>SoapObject Request = </code><code>new</code> <code>SoapObject(NAMESPACE, METHOD_NAME);</code>

<code>            </code><code>Request.addProperty(</code><code>"Celsius"</code><code>, </code><code>"32"</code><code>);</code>

<code>            </code><code>SoapSerializationEnvelope soapEnvelope = </code><code>new</code> <code>SoapSerializationEnvelope(SoapEnvelope.VER11);</code>

<code>            </code><code>soapEnvelope.dotNet = </code><code>true</code><code>;</code>

<code>            </code><code>soapEnvelope.setOutputSoapObject(Request);</code>

<code>            </code><code>HttpTransportSE transport= </code><code>new</code> <code>HttpTransportSE(URL);</code>

<code>            </code><code>transport.call(SOAP_ACTION, soapEnvelope);</code>

<code>            </code><code>SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();</code>

<code>            </code><code>Log.i(TAG, </code><code>"Result Celsius: "</code> <code>+ resultString);</code>

<code>        </code><code>catch</code><code>(Exception ex) {</code>

<code>            </code><code>Log.e(TAG, </code><code>"Error: "</code> <code>+ ex.getMessage());</code>

<code>        </code><code>SOAP_ACTION = </code><code>"http://tempuri.org/FahrenheitToCelsius"</code><code>;</code>

<code>        </code><code>METHOD_NAME = </code><code>"FahrenheitToCelsius"</code><code>;</code>

<code>            </code><code>Request.addProperty(</code><code>"Fahrenheit"</code><code>, </code><code>"100"</code><code>);</code>

<code>            </code><code>Log.i(TAG, </code><code>"Result Fahrenheit: "</code> <code>+ resultString);</code>

三. Android使用ksoap2調用C#中的webservice實作圖像上傳參考方法

   最近boss要求做android用戶端的圖檔上傳和下載下傳,就是調用伺服器的webservice接口,實作從android上傳圖檔到伺服器,然後從伺服器下載下傳圖檔到android用戶端。

需求下來了,開始動腦筋了呗。

   通常,我們調用webservice,就是伺服器和用戶端(浏覽器,android手機端等)之間的通信,其通信一般是傳 xml或json格式的字元串。對,就隻能是字元串。

我的思路是這樣的,從android端用io流讀取到要上傳的圖檔,用Base64編碼成位元組流的字元串,通過調用webservice把該字元串作為參數傳到伺服器端,服務端解碼該字元串,最後儲存到相應的路徑下。整個上傳過程的關鍵就是 以 位元組流的字元串 進行資料傳遞。下載下傳過程,與上傳過程相反,把伺服器端和用戶端的代碼相應的調換。

   不羅嗦那麼多,上代碼。流程是:把android的sdcard上某張圖檔 上傳到 伺服器下images 檔案夾下。    

   注:這隻是個demo,沒有UI界面,檔案路徑和檔案名都已經寫死,運作時,相應改一下就行。

1 .讀取android sdcard上的圖檔。

public void testUpload(){  

       try{  

           String srcUrl = "/sdcard/"; //路徑  

           String fileName = "aa.jpg";  //檔案名  

           FileInputStream fis = new FileInputStream(srcUrl + fileName);  

           ByteArrayOutputStream baos = new ByteArrayOutputStream();  

           byte[] buffer = new byte[1024];  

           int count = 0;  

           while((count = fis.read(buffer)) &gt;= 0){  

               baos.write(buffer, 0, count);  

           }  

           String uploadBuffer = new String(Base64.encode(baos.toByteArray()));  //進行Base64編碼  

           String methodName = "uploadImage";  

           connectWebService(methodName,fileName, uploadBuffer);   //調用webservice  

           Log.i("connectWebService", "start");  

           fis.close();  

       }catch(Exception e){  

           e.printStackTrace();  

       }  

   }  

connectWebService()方法:

//使用 ksoap2 調用webservice  

   private boolean connectWebService(String methodName,String fileName, String imageBuffer) {  

       String namespace = "http://134.192.44.105:8080/SSH2/service/IService";  // 命名空間,即伺服器端得接口,注:字尾沒加 .wsdl,  

                                                                               //伺服器端我是用x-fire實作webservice接口的  

       String url = "http://134.192.44.105:8080/SSH2/service/IService";   //對應的url  

       //以下就是 調用過程了,不明白的話 請看相關webservice文檔    

       SoapObject soapObject = new SoapObject(namespace, methodName);      

       soapObject.addProperty("filename", fileName);  //參數1   圖檔名  

       soapObject.addProperty("image", imageBuffer);   //參數2  圖檔字元串  

       SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(  

               SoapEnvelope.VER10);  

       envelope.dotNet = false;  

       envelope.setOutputSoapObject(soapObject);  

       HttpTransportSE httpTranstation = new HttpTransportSE(url);  

       try {  

           httpTranstation.call(namespace, envelope);  

           Object result = envelope.getResponse();  

           Log.i("connectWebService", result.toString());  

       } catch (Exception e) {  

       return false;  

2. 伺服器端的webservice代碼 :

public String uploadImage(String filename, String image) {  

   FileOutputStream fos = null;  

   try{  

       String toDir = "C:\\Program Files\\Tomcat 6.0\\webapps\\SSH2\\images";   //存儲路徑  

       byte[] buffer = new BASE64Decoder().decodeBuffer(image);   //對android傳過來的圖檔字元串進行解碼  

       File destDir = new File(toDir);    

       if(!destDir.exists()) destDir.mkdir();  

       fos = new FileOutputStream(new File(destDir,filename));   //儲存圖檔  

       fos.write(buffer);  

       fos.flush();  

       fos.close();  

       return "上傳圖檔成功!" + "圖檔路徑為:" + toDir;  

   }catch (Exception e){  

       e.printStackTrace();  

   return "上傳圖檔失敗!";  

}  

   對android 端進行 單元測試調用testUpload()方法,如果你看到綠條的話,說明調用成功!在伺服器下,就可以看到你上傳的圖檔了。。。。

   當然,這個demo很簡陋,沒有漂亮UI什麼的,但是這是 android端調用webservice進行上傳圖檔的過程。從伺服器下載下傳到android端,道理亦然。歡迎大家交流學習。。。。

   一:webService簡介

那麼什麼是webService呢?,它是一種基于SAOP協定的遠端調用标準,通過webservice可以将不同作業系統平台,不同語言,不同技術整合到一起。

   二:在AdroidManifest.xml中加入權限

&lt;!-- 通路網絡的權限 --&gt;

&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"

   &lt;uses-permission android:name="android.permission.INTERNET" /&gt;

&lt;/manifest&gt;

   三:導入ksoap2包

首先下載下傳KSOAP包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar包 複制到工程下的lib檔案件裡面

然後在android項目:右鍵-&gt;build path(建構路徑)-&gt;configure build path(添加外部歸檔)--選擇ksoap2

   四:編寫android可用戶端代碼

導入包庫:

import org.ksoap2.SoapEnvelope;  

import org.ksoap2.serialization.SoapObject;  

import org.ksoap2.serialization.SoapSerializationEnvelope; 

import org.ksoap2.transport.HttpTransportSE;

函數方法:

try { 

       final String SERVER_URL = "http://124.205.154.198:8081/Service.asmx";

       String nameSpace = "http://tempuri.org/";//命名空間

     String methodName = "Sum";//方法名

     String soapAction = "http://tempuri.org/Sum";//HelloWorld  命名空間/方法名

     //建立SoapObject執行個體

        SoapObject request = new SoapObject(nameSpace, methodName); 

        request.addProperty("a", "g"); //這個是傳遞參數的 當然了不要參數就不必寫這個了啊

        //request.addProperty("passonString", "Rajapandian"); //這個是傳遞參數的  

        //生成調用web service方法的soap請求消息

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

        envelope.dotNet = true; //設定.net web service

        envelope.setOutputSoapObject(request);//發送請求

        HttpTransportSE androidHttpTransport = new HttpTransportSE(SERVER_URL); 

        androidHttpTransport.call(soapAction, envelope);  

        Object result = (Object) envelope.getResponse(); 

        //textView.setText(e.getMessage());   

        textView.setText(result.toString());

        //textView.setText("7");

        new AlertDialog.Builder(this).setTitle("Hint").setMessage(result.toString()).setPositiveButton("OK", null).show();

        } 

       catch (Exception e) 

       {  

         System.out.println(e.getMessage());  

         textView.setText(e.getMessage()); 

         new AlertDialog.Builder(this).setTitle("Hint").setMessage(e.getMessage()).setPositiveButton("OK", null).show(); 

       }

   五:webService方法

[WebMethod]

   public string Sum(string a)

   {

       string c =a+"hello android";

       return c;

   }

四. 圖像傳輸中Base64編碼問題

   一. Base64的編碼規則

Base64編碼的思想是是采用64個基本的ASCII碼字元對資料進行重新編 碼。它将需要編碼的資料拆分成位元組數組。以3個位元組為一組。按順序排列24 位資料,再把這24位資料分成4組,即每組6位。再在每組的的最高位前補兩個0湊足一個位元組。這樣就把一個3位元組為一組的資料重新編碼成了4個位元組。當所 要編碼的資料的位元組數不是3的整倍數,也就是說在分組時最後一組不夠3個位元組。這時在最後一組填充1到2個0位元組。并在最後編碼完成後在結尾添加1到2個 “=”。

例:将對ABC進行BASE64編碼:

1、首先取ABC對應的ASCII碼值。A(65)B(66)C(67);

2、再取二進制值A(01000001)B(01000010)C(01000011);

3、然後把這三個位元組的二進制碼接起來(010000010100001001000011);

4、 再以6位為機關分成4個資料塊,并在最高位填充兩個0後形成4個位元組的編碼後的值,(00010000)(00010100)(00001001)(00000011),其中藍色部分為真實資料;

5、再把這四個位元組資料轉化成10進制數得(16)(20)(9)(3);

6、最後根據BASE64給出的64個基本字元表,查出對應的ASCII碼字元(Q)(U)(J)(D),這裡的值實際就是資料在字元表中的索引。

注:BASE64字元 表:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

   二.解碼 規則

解碼過程就是把4個位元組再還原成3個位元組再根據不同的資料形式把位元組數組重新整理 成資料。

   三. C#中的實作

編碼:

byte[] bytes = Encoding.Default.GetBytes("要轉換的字元");

string str = Convert.ToBase64String(bytes);

解 碼:

byte[] outputb = Convert.FromBase64String(str);

string orgStr = Encoding.Default.GetString(outputb);

C#圖檔的Base64編碼和解碼

圖檔的Base64編碼:

System.IO.MemoryStream m =new System.IO.MemoryStream();

System.Drawing.Bitmap bp =new System.Drawing.Bitmap(@“c:\demo.GIF”);

bp.Save(m, System.Drawing.Imaging.ImageFormat.Gif);

byte[]b= m.GetBuffer();

string base64string=Convert.ToBase64String(b);

Base64字元串解碼:

byte[] bt = Convert.FromBase64String(base64string);

System.IO.MemoryStream stream =new System.IO.MemoryStream(bt);

Bitmap bitmap =new Bitmap(stream);

pictureBox1.Image = bitmap;

本文轉自 huohe2009 51CTO部落格,原文連結:http://blog.51cto.com/zhaojie/1209816

繼續閱讀