zoukankan      html  css  js  c++  java
  • Android使用ksoap2调用C#中的webservice实现图像上传

     目录:

       一. android使用ksoap2调用webservice

       二. 异步调用

       三. Android使用ksoap2调用C#中的webservice实现图像上传参考方法

       四. 图像传输中Base64编码问题

    一. android使用ksoap2调用webservice

    这个话题很多文章中做过讨论,这里需要说明的一点,You can't do Network operations on the main thread. Checkout :http://developer.android.com/reference/android/os/AsyncTask.htmlfor painless background threading :) (参考:http://stackoverflow.com/questions/11969071/android-os-networkonmainthreadexception-for-webservice-ksoap),即调用webservice的操作必须是异步执行的(在2.2及之前版本可能不需要)。

       android使用ksoap2调用webservice的基本代码如下:

    [java] view plain copy
     
    1. package com.example.webserviceexample;  
    2. import java.io.IOException;  
    3. import org.ksoap2.SoapEnvelope;  
    4. import org.ksoap2.SoapFault;  
    5. import org.ksoap2.serialization.SoapObject;  
    6. import org.ksoap2.serialization.SoapPrimitive;  
    7. import org.ksoap2.serialization.SoapSerializationEnvelope;  
    8. import org.ksoap2.transport.HttpTransportSE;  
    9. import org.xmlpull.v1.XmlPullParserException;  
    10. import android.app.Activity;  
    11. import android.os.Bundle;  
    12. import android.view.Menu;  
    13. import android.view.View;  
    14. import android.view.View.OnClickListener;  
    15. import android.widget.Button;  
    16. import android.widget.EditText;  
    17. import android.widget.TextView;  
    18. public class MainActivity extends Activity {  
    19.     final static String NAMESPACE = "http://tempuri.org/";  
    20.     final static String METHOD_NAME = "CelsiusToFahrenheit";  
    21.     final static String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";  
    22.     final static String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";  
    23.     TextView sonuc;  
    24.     EditText deger;  
    25.     Button hesapla;  
    26.     @Override  
    27.     public void onCreate(Bundle savedInstanceState) {  
    28.         super.onCreate(savedInstanceState);  
    29.         setContentView(R.layout.activity_main);  
    30.         deger = (EditText) findViewById(R.id.deger);  
    31.         sonuc = (TextView) findViewById(R.id.flag);  
    32.         hesapla = (Button) findViewById(R.id.hesapla);  
    33.         hesapla.setOnClickListener(new OnClickListener() {  
    34.             public void onClick(View v) {  
    35.                 //request info  
    36.                 SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);  
    37.                 Request.addProperty("Celcius",deger.getText().toString());  
    38.                 //envelope  
    39.                 SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);  
    40.                 soapEnvelope.dotNet = true; //.NET = true, php = false  
    41.                 //putting request to the envelope  
    42.                 soapEnvelope.setOutputSoapObject(Request);  
    43.                 //transferring data  
    44.                 HttpTransportSE aht = new HttpTransportSE(URL); //prepare  
    45.                 //start  
    46.                 try {  
    47.                         aht.call(SOAP_ACTION, soapEnvelope);  
    48.                 }  
    49.                 catch (IOException e) {  
    50.                     e.printStackTrace();  
    51.                 }  
    52.                 catch (XmlPullParserException e)  
    53.                 {  
    54.                     e.printStackTrace();  
    55.                 }  
    56.                 //waiting and getting response.  
    57.                 String result;  
    58.                 try {  
    59.                     // we are creating SoapPrimitive Object as waiting for simple variable.  
    60.                     result = "Fahrenheit:" + soapEnvelope.getResponse();  
    61.                     //writing the result to the textView  
    62.                     sonuc.setText(result);  
    63.                 }  
    64.                 catch (SoapFault e) {  
    65.                     e.printStackTrace();  
    66.                 }  
    67.             }  
    68.         });  
    69.     }  
    70.     @Override  
    71.     public boolean onCreateOptionsMenu(Menu menu) {  
    72.         getMenuInflater().inflate(R.menu.activity_main, menu);  
    73.         return true;  
    74.     }  
    75. }  

    二. 异步调用

        上述代码中,没有异步调用,是不能正常执行的,会有如下警告:

    [xml] view plain copy
     
    1. 08-15 11:45:26.294: E/AndroidRuntime(641): FATAL EXCEPTION: main  
    2. 08-15 11:45:26.294: E/AndroidRuntime(641): android.os.NetworkOnMainThreadException  

    正确的步骤中,需要把操作webservice的代码放入异步执行中,下面是异步执行的一个完整示例(同时可参考:http://stackoverflow.com/questions/8322057/android-os-networkonmainthreadexception-exception-while-trying-to-call-a-webserv):

    [java] view plain copy
     
    1. import org.ksoap2.SoapEnvelope;  
    2. import org.ksoap2.serialization.SoapObject;  
    3. import org.ksoap2.serialization.SoapPrimitive;  
    4. import org.ksoap2.serialization.SoapSerializationEnvelope;  
    5. import org.ksoap2.transport.HttpTransportSE;  
    6. import android.app.Activity;  
    7. import android.os.AsyncTask;  
    8. import android.os.Bundle;  
    9. import android.util.Log;  
    10. public class MainActivity extends Activity {  
    11.     private String TAG ="Vik";  
    12.     @Override  
    13.     protected void onCreate(Bundle savedInstanceState) {  
    14.         super.onCreate(savedInstanceState);  
    15.         setContentView(R.layout.activity_main);  
    16.         AsyncCallWS task = new AsyncCallWS();  
    17.         task.execute();  
    18.     }  
    19.     private class AsyncCallWS extends AsyncTask<Void, Void, Void> {  
    20.         @Override  
    21.         protected Void doInVoid...  params) {  
    22.             Log.i(TAG, "doInBackground");  
    23.             calculate();  
    24.             return null;  
    25.         }  
    26.         @Override  
    27.         protected void onPostExecute(Void result) {  
    28.             Log.i(TAG, "onPostExecute");  
    29.         }  
    30.         @Override  
    31.         protected void onPreExecute() {  
    32.             Log.i(TAG, "onPreExecute");  
    33.         }  
    34.         @Override  
    35.         protected void onProgressUpdate(Void... values) {  
    36.             Log.i(TAG, "onProgressUpdate");  
    37.         }  
    38.     }  
    39.     public void calculate()  
    40.     {  
    41.         String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";  
    42.         String METHOD_NAME = "CelsiusToFahrenheit";  
    43.         String NAMESPACE = "http://tempuri.org/";  
    44.         String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";  
    45.         try {  
    46.             SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);  
    47.             Request.addProperty("Celsius", "32");  
    48.             SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);  
    49.             soapEnvelope.dotNet = true;  
    50.             soapEnvelope.setOutputSoapObject(Request);  
    51.             HttpTransportSE transport= new HttpTransportSE(URL);  
    52.             transport.call(SOAP_ACTION, soapEnvelope);  
    53.             SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();  
    54.             Log.i(TAG, "Result Celsius: " + resultString);  
    55.         }  
    56.         catch(Exception ex) {  
    57.             Log.e(TAG, "Error: " + ex.getMessage());  
    58.         }  
    59.         SOAP_ACTION = "http://tempuri.org/FahrenheitToCelsius";  
    60.         METHOD_NAME = "FahrenheitToCelsius";  
    61.         try {  
    62.             SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);  
    63.             Request.addProperty("Fahrenheit", "100");  
    64.             SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);  
    65.             soapEnvelope.dotNet = true;  
    66.             soapEnvelope.setOutputSoapObject(Request);  
    67.             HttpTransportSE transport= new HttpTransportSE(URL);  
    68.             transport.call(SOAP_ACTION, soapEnvelope);  
    69.             SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();  
    70.             Log.i(TAG, "Result Fahrenheit: " + resultString);  
    71.         }  
    72.         catch(Exception ex) {  
    73.             Log.e(TAG, "Error: " + ex.getMessage());  
    74.         }  
    75.     }  
    76. }  

    三. Android使用ksoap2调用C#中的webservice实现图像上传参考方法

    博客园“与时俱进”同时有相关的一篇博文(http://www.cnblogs.com/top5/archive/2012/02/16/2354517.html)可作为参考,全文如下:

       最近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)) >= 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) {  

               e.printStackTrace();  

           }  

           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端,道理亦然。欢迎大家交流学习。。。。

    ljd_198641给出了Android使用ksoap2调用C#中的webservice函数方法(参考:http://blog.csdn.net/ljd_1986413/article/details/6928051),全文如下:

       一:webService简介

    那么什么是webService呢?,它是一种基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合到一起。

       二:在AdroidManifest.xml中加入权限

    <!-- 访问网络的权限 -->

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"

       <uses-permission android:name="android.permission.INTERNET" />
    </manifest>

       三:导入ksoap2包

    首先下载KSOAP包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar包 复制到工程下的lib文件件里面

    然后在android项目:右键->build path(构建路径)->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编码问题

       在android java与c#进行图像传输时涉及到 Base64编解码,涉及到的知识点如下(参考:http://www.cnblogs.com/chenqingwei/archive/2010/06/28/1766689.html):

       一. 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;

    本文出自 “独钓寒江雪” 博客,请务必保留此出处http://zhaojie.blog.51cto.com/1768828/1209816

  • 相关阅读:
    ubuntu安装docker-compose
    docker-compose常用命令(持续更新...)
    docker运行jpress
    gcc -o选项:指定输出文件
    gcc -c:只编译不链接,仅生成目标文件
    WMWare下安装centOS7,并使用xshell进行连接记录.
    主线程和子线程多种情况小探讨
    Sleep的本质
    为什么要对多线程进行加锁操作呢
    list操作相关总结
  • 原文地址:https://www.cnblogs.com/hbtmwangjin/p/8087244.html
Copyright © 2011-2022 走看看