首页 > 代码库 > 关于安卓调用C#的WebService上传图片问题(不使用ksoap2)

关于安卓调用C#的WebService上传图片问题(不使用ksoap2)

============问题描述============


小弟初学安卓开发。最近需要做一个图片上传的功能。
我是用java开发安卓,调用C#的WebService。在网上找到一大堆资料,几乎全部是用ksoap2包的。
请注意,我想做的是不用ksoap包的。
我现在的方法是从android端用读取到要上传的图片,用Base64编码成字节流的字符串,通过调用webservice把该字符串作为参数传到服务器端,服务端解码该字符串,最后保存到相应的路径下。整个上传过程的关键就是以字节流的字符串进行数据传递。
功能代码如下:

WebService:
public string uploadImage(string filename, string image)
        {
            FileStream fs = null;
            try
            {
                string toDir = "E:\\C# Project\\Dev\\GPRSDataIn\\GPRSDataIn\\Images";
                fs = new FileStream(filename, FileMode.Create);

                byte[] buffer = Encoding.UTF8.GetBytes(image);
                fs.Write(buffer, 0, buffer.Length);
                fs.Flush();
                fs.Close();
                return "上传图片成功!" + "图片路径为:" + toDir;
            }
            catch (Exception e)
            {

            }
            return "上传图片失败!";
        }

安卓端:调用WebService方法
public class UploadUtil {
	
	private static HttpConnSoap Soap = new HttpConnSoap();
	public static void uploadImage(String filename, String image) {
		ArrayList<String>arrayList=new ArrayList<String>();
		ArrayList<String>brrayList=new ArrayList<String>();
		
		arrayList.clear();
		brrayList.clear();

		arrayList.add("filename");
		arrayList.add("image");
		brrayList.add(filename);
		brrayList.add(image);

		Soap.GetWebServre("uploadImage", arrayList, brrayList);
	}
}


public class HttpConnSoap {
	/**
	 * 获取返回的InputStream,为了增强通用性,在方法内不对其进行解析。
	 * 
	 * @param methodName
	 *            webservice方法名
	 * @param Parameters
	 *            webservice方法对应的参数名
	 * @param ParValues
	 *            webservice方法中参数对应的值
	 * @return 未解析的InputStream
	 */
	public InputStream GetWebServre(String methodName, ArrayList<String> Parameters, ArrayList<String> ParValues) {
		// 指定URL地址,我这里使用的是常量。
		String ServerUrl = "http://www.bsri.com.cn:99/ws3/Service1.asmx";

		// soapAction = 命名空间 + 方法名
		String soapAction = "http://tempuri.org/" + methodName;

		// 拼凑requestData
		String soap = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
				+ "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
				+ "<soap:Body />";
		String tps,vps,ts;
		String mreakString = "";
		mreakString = "<" + methodName + " xmlns=\"http://tempuri.org/\">";

        for (int i = 0; i < Parameters.size(); i++)
        {
            tps = Parameters.get (i).toString();
            //设置该方法的参数为.net webService中的参数名称
            vps = ParValues.get (i).toString();
            ts = new String("<" + tps + ">" + vps + "</" + tps + ">");
            mreakString = mreakString + ts;
        }
		mreakString = mreakString + "</" + methodName + ">";
		String soap2 = "</soap:Envelope>";
		String requestData = soap + mreakString + soap2;
		// 其上所有的数据都是在拼凑requestData,即向服务器发送的数据

		try {
			URL url = new URL(ServerUrl); // 指定服务器地址
			HttpURLConnection con = (HttpURLConnection) url.openConnection();// 打开链接
			byte[] bytes = requestData.getBytes("utf-8"); // 指定编码格式,可以解决中文乱码问题
			con.setDoInput(true); // 指定该链接是否可以输入
			con.setDoOutput(true); // 指定该链接是否可以输出
			con.setUseCaches(false); // 指定该链接是否只用caches
			con.setConnectTimeout(6000); // 设置超时时间
			con.setRequestMethod("POST"); // 指定发送方法名,包括Post和Get。
			con.setRequestProperty("Content-Type", "text/xml;charset=utf-8"); // 设置(发送的)内容类型
			con.setRequestProperty("SOAPAction", soapAction); // 指定soapAction
			con.setRequestProperty("Content-Length", "" + bytes.length); // 指定内容长度

			// 发送数据
			OutputStream outStream = con.getOutputStream();
			outStream.write(bytes);
			outStream.flush();
			outStream.close();

			// 获取数据
			// con.connect();

			BufferedInputStream ois = new BufferedInputStream(
					con.getInputStream());
			byte[] revBytes = new byte[20480];
			ois.read(revBytes);
			//InputStream inputStream = new ByteArrayInputStream(revBytes);

			String s = new String(revBytes);
			String newS = s.replaceAll("&lt;", "<");
			String newS1 = newS.replaceAll("&gt;", ">");
			ByteArrayInputStream bais = new ByteArrayInputStream(
					newS1.getBytes());
			return bais;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

}

触发上传方法:
@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.selectImage:
			/*** * 这个是调用android内置的intent,来过滤图片文件 ,同时也可以过滤其他的 */
			Intent intent = new Intent();
			intent.setType("image/*");
			intent.setAction(Intent.ACTION_GET_CONTENT);
			startActivityForResult(intent, 1);
			break;
		case R.id.uploadImage:
			if (picPath == null) {
				Toast.makeText(Upload.this, "请选择图片!", 1000).show();
			} else {
				final File file = new File(picPath);
				if (file != null) {
					UploadUtil.uploadImage(imgName, photodata);
				}
			}
			break;
		default:
			break;
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == Activity.RESULT_OK) {
			/** * 当选择的图片不为空的话,在获取到图片的途径 */
			Uri uri = data.getData();
			try {
				Cursor cursor = getContentResolver().query(uri, null, null,
						null, null);
				if (cursor != null) {
					ContentResolver cr = this.getContentResolver();
					cursor.moveToFirst();
					String path = cursor.getString(1); // 图片文件路径
					imgName = cursor.getString(3); // 图片文件名

					if (path.endsWith("jpg") || path.endsWith("png")) {
						picPath = path;
						Bitmap bitmap = BitmapFactory.decodeStream(cr
								.openInputStream(uri));
						imageView.setImageBitmap(bitmap);
						
						FileInputStream fis = new FileInputStream(path);
						ByteArrayOutputStream baos = new ByteArrayOutputStream();
						byte[] buffer = new byte[20480];
						int count = 0;
						while ((count = fis.read(buffer)) >= 0) {
							baos.write(buffer, 0, count);
						}

						byte[] bytes = baos.toByteArray();

						photodata = Base64
								.encodeToString(bytes, Base64.DEFAULT);
					} else {
						alert();
					}
				} else {
					alert();
				}
			} catch (Exception e) {
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

我感觉理论上是没有什么问题的,但是实际上,执行到调用WebService的时候,拼接请求时, ts = new String("<" + tps + ">" + vps + "</" + tps + ">");这里可能是图片转base64编码的String串长度太长,导致内存溢出。
如何解决,望各位大神指教!或者程序有什么错还请大神们指出,或者教我用合适的方法。小弟分不多,还请见谅。

============解决方案1============


	void submieGson(String users){
		try {

			HttpClient httpClient = new DefaultHttpClient();
			
			HttpPost httppost = new HttpPost("http://*/jsonws/frank/ftocservice/getUserInfo");
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("users", users));
			nameValuePairs.add(new BasicNameValuePair("file", getFileString()));
			
			httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8));
			
			HttpResponse response = httpClient.execute(httppost);
			System.out.println("rescode ="+response.getStatusLine().getStatusCode());
			if (response.getStatusLine().getStatusCode() == 200) {
				String str = EntityUtils.toString(response.getEntity(),"utf-8");
				System.out.println("json ========"+str);
				Message msg = Message.obtain();
				msg.obj = str;
				mHandler.sendMessage(msg);
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


String getFileString() {
		String fileStream = null;
		FileInputStream fis;
		try {
			fis = new FileInputStream(Environment.getExternalStorageDirectory()
					.getPath() + "/QuickCheck/image/temp.png");

			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int count = 0;
			while ((count = fis.read(buffer)) >= 0) {
				baos.write(buffer, 0, count);
			}
			fis.close();
			fileStream = new String(Base64.encode(baos.toByteArray(),
					Base64.DEFAULT)); // 进行Base64编码
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return fileStream;
	}


使用post进行提交

关于安卓调用C#的WebService上传图片问题(不使用ksoap2)