日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁編程開發(fā)Android → 利用WCF與Android實現(xiàn)圖片上傳并傳遞參數(shù)

      利用WCF與Android實現(xiàn)圖片上傳并傳遞參數(shù)

      前往專題相關(guān)軟件相關(guān)文章發(fā)表評論 來源:西西整理時間:2013/9/2 23:23:17字體大。A-A+

      作者:西西點擊:217次評論:1次標(biāo)簽: WCF Android

      • 類型:源碼相關(guān)大。79KB語言:中文 評分:5.0
      • 標(biāo)簽:
      立即下載

      最近做一個項目后端使用WCF接收Android手機拍照并帶其它參數(shù)保存到服務(wù)器里;剛好把最近學(xué)習(xí)的WCF利用上,本以為是個比較簡單的功能應(yīng)該很好實現(xiàn),沒想到其中碰到不少問題,在網(wǎng)上搜索很久一直沒有想到的解決方案,最后實現(xiàn)對數(shù)據(jù)流的分段寫入然后后端再來解析流實現(xiàn)的此功能;后端運用WCF中的REST來接收數(shù)據(jù);REST還是比較簡單的知識,若是不懂可以簡單網(wǎng)上了解一下;下面我們先了解一些本次運用到的理論知識:

      一:理論知識

      由于低層協(xié)議特性限制,WCF的流模式只支持如下四種:1:BasicHttpBinding 2:NetTcpBinding 3:NetNamedPipeBinding 4:WebHttpBinding

      1.設(shè)置TransferMode。它支持四種模式(Buffered、Streamed、StreamedRequest、StreamedResponse),請根據(jù)具體情況設(shè)置成三種Stream模式之一。

      2.修改MaxReceivedMessageSize。該值默認大小為64k,因此,當(dāng)傳輸數(shù)據(jù)大于64k時,則拋出CommunicationException異常。  

      3.修改receiveTimeout 和sendTimeout。大數(shù)據(jù)傳送時間較長,需要修改這兩個值,以免傳輸超時。

      二:解決問題

      WCF如果使用Stream做為參數(shù)時只能唯一一個,不能有其它另外的參數(shù),這個也是本次碰到要重點解決的一個問題;可是我們Android手機除的圖片還要有其它的參數(shù),最后決定采用手機端把參數(shù)跟圖片都一起寫入Stream里面,后端WCF再來解析這個參數(shù)的流;

      下面就是定義好Stream的格式,傳過來的Stream分成三部分: 參數(shù)信息長度  參數(shù)信息   圖片

      1 參數(shù)信息長度(1字節(jié)):用于存放參數(shù)信息的長度(以字節(jié)為單位);

      2 參數(shù)信息: 除圖片以外的參數(shù),以JSON的形式存放如{"type":"jpg","EmployeeID":"12","TaskID":"13"}

      3 圖片:圖片的字節(jié)

      三:WCF編碼內(nèi)容

      1:我們首先定義一個WCF契約,由于我們運用REST(在命名空間ServiceModel.Web下面)契約IAndroidInfo內(nèi)容如下,采用POST方式進行接收:

      using System.ServiceModel;
      using System.Runtime.Serialization;
      using System.ServiceModel.Web;
      using System.IO;
      
      namespace Coreius.CEIMS.AndroidInterface
      {
          [ServiceContract]
          public interface IAndroidInfo
          {
               [WebInvoke(UriTemplate = "GpsUpFile", Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, 
      ResponseFormat = WebMessageFormat.Json)]
              bool GpsUpFile(Stream ImageContext);
          }
      }

      2:根據(jù)契約我們定義服務(wù)的內(nèi)容,接收一個流的參數(shù)內(nèi)容,首先把這個Stream轉(zhuǎn)化成字節(jié),然后根據(jù)我們先前約定好的內(nèi)容獲得第一個字節(jié)的值,再根據(jù)此值定義我們另外三個參數(shù)的字節(jié)長度,再通過JSON轉(zhuǎn)換格式把它里面的三個參數(shù)值取出來,最后其它字節(jié)是存放一張手機拍的照片,把它存放在于們服務(wù)器D盤文件夾下

      using System.Linq;
      using System.Text;
      using System.ServiceModel;
      using System.ServiceModel.Web;
      using System.IO;
      using Newtonsoft.Json;
      
      namespace Coreius.CEIMS.AndroidService
      {
          public class AndroidInfoService:IAndroidInfo
          {
      
            public bool GpsUpFile(Stream ImageContext)
              {
                  byte[] m_Bytes = ReadToEnd(ImageContext);
                  int len = (int)m_Bytes[0];
      
                  byte[] data = m_Bytes.Skip(1).Take(len).ToArray();
                  string Jsonstr = System.Text.Encoding.Default.GetString(data);
      
                  JsonModel item = JsonConvert.DeserializeObject<JsonModel>(Jsonstr);
                  string ImageType=item.type;
                  string EmployeeID=item.EmployeeID;
                  string TaskID=item.TaskID;
      
                  byte[] Imagedata = m_Bytes.Skip(1 + len).ToArray();
      
                  string DiskName = "d:";
                  string FileAddress = "\\UpLoad\\";
                  string LocationAddress = DiskName + FileAddress;
                  if (!DirFileHelper.IsExistDirectory(LocationAddress))
                  {
                      DirFileHelper.CreateDirectory(LocationAddress);
                  }
      
                  string ImageName = DateTime.Now.ToString("yyyyMMddhhmmss.") + ImageType;
                  string ImagePath = LocationAddress + ImageName;
                  if (!File.Exists(ImagePath))
                  {
                      try
                      {
                          System.IO.File.WriteAllBytes(ImagePath, Imagedata);
                          ImageContext.Close();
                          return true;
                      }
                      catch
                      {
                          return false;
                      }
                  }
                  else
                  {
                      return false;
                  }
              }
          }
      }

      上面的代碼用到幾個方法,比如把流轉(zhuǎn)化成字節(jié)、把JSON轉(zhuǎn)化成實現(xiàn)等,代碼如下:

      public byte[] ReadToEnd(System.IO.Stream stream)
              {
                  long originalPosition = 0;
      
                  if (stream.CanSeek)
                  {
                      originalPosition = stream.Position;
                      stream.Position = 0;
                  }
      
                  try
                  {
                      byte[] readBuffer = new byte[4096];
      
                      int totalBytesRead = 0;
                      int bytesRead;
      
                      while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                      {
                          totalBytesRead += bytesRead;
      
                          if (totalBytesRead == readBuffer.Length)
                          {
                              int nextByte = stream.ReadByte();
                              if (nextByte != -1)
                              {
                                  byte[] temp = new byte[readBuffer.Length * 2];
                                  Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                                  Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                                  readBuffer = temp;
                                  totalBytesRead++;
                              }
                          }
                      }
      
                      byte[] buffer = readBuffer;
                      if (readBuffer.Length != totalBytesRead)
                      {
                          buffer = new byte[totalBytesRead];
                          Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                      }
                      return buffer;
                  }
                  finally
                  {
                      if (stream.CanSeek)
                      {
                          stream.Position = originalPosition;
                      }
                  }
              }
      
      
      
          public class JsonModel
          {
              public string type { get; set; }
              public string EmployeeID { get; set; }
              public string TaskID { get; set; }
          }

      3:新建一個文本,然后修改其后綴名為.svc,作為我們發(fā)布服務(wù)(宿主為IIS)讓Android手機調(diào)用, 然后把下面的代碼寫入

      <%@ ServiceHost Language="C#" Debug="true" Service="Coreius.CEIMS.AndroidService.AndroidInfoService" %>

      修改Web.config里面的內(nèi)容:

      <?xml version="1.0" encoding="utf-8"?>
      <configuration>
        <appSettings>
          <add key="ConnectionString" value="server=127.0.0.1;database=Coreius;uid=sa;pwd=admin"/>
        </appSettings>
        <system.web>
          <compilation debug="true" targetFramework="4.0" />
        </system.web>
        <system.serviceModel>
          <behaviors>
            <endpointBehaviors>
              <behavior name="webHttp">
                <webHttp helpEnabled="true"/>
              </behavior>
            </endpointBehaviors>
            <serviceBehaviors>
              <behavior name="MapConfigBehavior">
                <!-- 為避免泄漏元數(shù)據(jù)信息,請在部署前將以下值設(shè)置為 false 并刪除上面的元數(shù)據(jù)終結(jié)點 -->
                <serviceMetadata httpGetEnabled="true"/>
                <!-- 要接收故障異常詳細信息以進行調(diào)試,請將以下值設(shè)置為 true。在部署前設(shè)置為 false 以避免泄漏異常信息 -->
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
              </behavior>
            </serviceBehaviors>
          </behaviors>
      
          <bindings>
            <webHttpBinding>
              <binding name="webHttpBindConfig" receiveTimeout="00:30:00" sendTimeout="00:30:00" maxReceivedMessageSize="104857600" transferMode="Streamed">
                <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
                <security mode="None"></security>
              </binding>
            </webHttpBinding>
          </bindings>
          <services>
            <service name="Coreius.CEIMS.AndroidService.AndroidInfoService" behaviorConfiguration="MapConfigBehavior">
              <endpoint binding="webHttpBinding" contract="Coreius.CEIMS.AndroidInterface.IAndroidInfo" bindingConfiguration="webHttpBindConfig" 
      
      behaviorConfiguration="webHttp"/> 
            </service>
          </services>
        </system.serviceModel>
      </configuration>

      此處有些要注意的地方:

      (1):此處采用的是webHttpBinding 所以一定要設(shè)置behaviorConfiguration才會有效果,其中helpEnabled="true"則是為實現(xiàn)可以在發(fā)布可以查看幫助信息    

              <behavior name="webHttp">
                <webHttp helpEnabled="true"/>
              </behavior>

      (2):為了實現(xiàn)上傳大文件所以我們要如下設(shè)置最大值,其中security是設(shè)置訪問服務(wù)的認證,此處是把它設(shè)置成為不認證

            <webHttpBinding>
              <binding name="webHttpBindConfig" receiveTimeout="00:30:00" sendTimeout="00:30:00" maxReceivedMessageSize="104857600" transferMode="Streamed">
                <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
                <security mode="None"></security>
              </binding>
            </webHttpBinding>

      4:編寫完上面的代碼后就可以服務(wù)器IIS上部署這個WCF服務(wù):

      四:Android編碼

      由于Android手機端的代碼是另外一個朋友編寫,所以就把大體的代碼貼出來,大體的原理就是把參數(shù)跟圖片寫入流,然后調(diào)用部署好的WCF服務(wù)

      代碼一:因為服務(wù)器不是公用的,所以下面的IP我就隨便修改的一個;

      private void toUploadFile(File file) throws FileNotFoundException {
              String result = null;
              requestTime= 0;
              int res = 0;
              long requestTime = System.currentTimeMillis();
              long responseTime = 0;
              //封裝參數(shù)信息
              JSONObject jsonObject = new JSONObject();
              try {
                  jsonObject.put("EmployeeID", MainActivity.guid);
                  jsonObject.put("TaskID", "e52df9b4-ee3b-46c5-8387-329b76356641");
                  String[] type = file.getName().split("\\.");
                  jsonObject.put("type", type[type.length-1]);
              } catch (JSONException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              /**上傳文件*/
              HttpParams httpParameters = new BasicHttpParams();
              HttpConnectionParams.setConnectionTimeout(httpParameters, 1000*30);
              HttpConnectionParams.setSoTimeout(httpParameters, 1000*30);
              HttpConnectionParams.setTcpNoDelay(httpParameters, true);
              String path = PictureUtil.zipNewImage(file);    //壓縮文件后返回的文件路徑
              byte[] bytes = null;
              InputStream is;
              File myfile = new File(path);
              try {
                  is = new FileInputStream(path);
                  bytes = new byte[(int) myfile.length()];
                  int len = 0;
                  int curLen = 0;
                  while ((len = is.read(bytes)) != -1) {
                      curLen += len;
                      is.read(bytes);
                  }
                  is.close();
              } catch (FileNotFoundException e1) {
                  // TODO Auto-generated catch block
                  e1.printStackTrace();
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              byte[] updata = GpsImagePackage.getPacket(jsonObject.toString(), bytes);    //參數(shù)與文件封裝成單個數(shù)據(jù)包
              HttpClient httpClient = new DefaultHttpClient(httpParameters);
              HttpPost httpPost = new HttpPost(MyUrl.upload_file);
              HttpResponse httpResponse;
              //單個文件流上傳
              InputStream input = new ByteArrayInputStream( updata );
              InputStreamEntity reqEntity;
              reqEntity = new InputStreamEntity(input, -1);
              reqEntity.setContentType("binary/octet-stream");
              reqEntity.setChunked(true);
              httpPost.setEntity(reqEntity);
              try {
                  httpResponse = httpClient.execute(httpPost);
                  responseTime = System.currentTimeMillis();
                  this.requestTime = (int) ((responseTime-requestTime)/1000);
                  res = httpResponse.getStatusLine().getStatusCode();
                  if (httpResponse.getStatusLine().getStatusCode() ==200) {
                      Log.e(TAG, "request success");
                      Log.e(TAG, "result : " + result);
                      return;
                  } else {
                      Log.e(TAG, "request error");
                      sendMessage(UPLOAD_SERVER_ERROR_CODE,"上傳失。篶ode=" + res);
                      return;
                  }
                  } catch (ClientProtocolException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
          }
      package com.anthony.util;
      /**
       * 服務(wù)器端接口
       * @author YWJ
       *
       */
      public class MyUrl {
          public static String upload_GPS = "http://122.199.19.23:8088/AndroidInfoService.svc/SetGpsInfo";
      }

      代碼二:

      package com.anthony.util;
      public class GpsImagePackage {
          public GpsImagePackage() {
              // TODO Auto-generated constructor stub
          }
          //封裝字節(jié)數(shù)組與參數(shù)
          public static byte[] getPacket(String json,byte[] image){
              byte[] jsonb = json.getBytes();
              int length = image.length + jsonb.length;
              System.out.println(image.length +"    "+ jsonb.length);
              byte[] bytes = new byte[length+1];
              byte[] lengthb = InttoByteArray(jsonb.length, 1);
              System.arraycopy(lengthb, 0, bytes, 0, 1);
              System.arraycopy(jsonb, 0, bytes, 1, jsonb.length);
              System.arraycopy(image, 0, bytes, 1+jsonb.length, image.length);
              return bytes;
          }
          //將int轉(zhuǎn)換為字節(jié)數(shù)組
          public static byte[] InttoByteArray(int iSource, int iArrayLen) {
              byte[] bLocalArr = new byte[iArrayLen];
              for ( int i = 0; (i < 4) && (i < iArrayLen); i++) {
                   bLocalArr[i] = (byte)( iSource>>8*i & 0xFF );
              }
               return bLocalArr;
          }
           // 將byte數(shù)組bRefArr轉(zhuǎn)為一個整數(shù),字節(jié)數(shù)組的低位是整型的低字節(jié)位
           public static int BytestoInt(byte[] bRefArr) {
               int iOutcome = 0;
               byte bLoop;
               for ( int i =0; i<bRefArr.length ; i++) {
                  bLoop = bRefArr[i];
                  iOutcome+= (bLoop & 0xFF) << (8 * i);
               }
              return iOutcome;
           }
      }

      五:運行效果:

        相關(guān)評論

        閱讀本文后您有什么感想? 已有人給出評價!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過難過
        • 5 囧
        • 3 圍觀圍觀
        • 2 無聊無聊

        熱門評論

        最新評論

        發(fā)表評論 查看所有評論(1)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字數(shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)