关闭

Android 基于Web Service的应用之天气预报

标签: web serviceandroidandroid应用android平台手机系统
1093人阅读 评论(0) 收藏 举报
分类:

       我们都知道Web Service具有使用标准协议规范、使用协约的规范性、高度集成能力、完好的封装性、松散耦合等五大特点。正是因为这样Web Service就像Web上的构件编程,开发人员通过调用Service应用编程接口,将Web Service集成进他们的应用程序,就像调用本地服务一样,同时开发人员可以跨平台和使用任何编程语言。这些优点不仅减少了开发人员的开发成本从而可以将精力投入到挖掘软件的商业价值中,同时这也是面向构件接口编程的一种很好的体现。Web Service的核心技术基于XML标准,主要包括SOAP协议、ASDL描述、UDDI协议。Web Service主要是对一些已经存在的技术进行包装,因此它是基于现有的技术的一种整合技术。这些技术均在W3c上可以学习到。
       Android应用通常是运行在手机平台上,手机系统的硬件资源是有限的,不管是存储能力还是计算能力都是有限的,在Android系统上开发、运行的一些简单用户、小型用户是可能的,但是当进行大量的复杂计算时还是只能不是在远程服务器上。为了让Android应用与远程服务器之间进行交互,可以采用java的RMI技术,但这种技术要求远程服务器程序必须是java实现的,也可以采用CORBA技术,但这种技术相对复杂,因此采用Web Service是一种不错的选择。

       下面以一个Android的应用来调用Web Service实现天气预报功能。

        在开始之前我们必须先找到一个可以对外提供天气预报的Web Service如天气Web Service,同时也可以在该网站上下载天气预报所需要的各种图标等等。同时还得在项目中导入android-support-v4.jar和ksoap2-android-assembly-3.0.0-RC.4-jar-with-dependencies.jar两个jar包,这样才可以实现其功能。这两个jar包是Google为Android平台提供开发Web Service的。下面就是该应用的部分源码
public class WebServiceUtil
{
 // 定义Web Service的命名空间
 static final String SERVICE_NS = "http://WebXml.com.cn/";
 // 定义Web Service提供服务的URL
 static final String SERVICE_URL =
  "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx";

 // 调用远程Web Service获取省份列表
 public static List<String> getProvinceList()
 {
  // 调用的方法
  final String methodName = "getRegionProvince";
  // 创建HttpTransportSE传输对象
  final HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
  ht.debug = true;
  // 使用SOAP1.1协议创建Envelop对象
  final SoapSerializationEnvelope envelope =
   new SoapSerializationEnvelope(SoapEnvelope.VER11);
  // 实例化SoapObject对象
  SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
  envelope.bodyOut = soapObject;
  // 设置与.Net提供的Web Service保持较好的兼容性
  envelope.dotNet = true;  
  FutureTask<List<String>> task = new FutureTask<List<String>>(
  new Callable<List<String>>()
  {
   @Override
   public List<String> call()
    throws Exception
   {
    // 调用Web Service
    ht.call(SERVICE_NS + methodName, envelope);
    if (envelope.getResponse() != null)
    {
     // 获取服务器响应返回的SOAP消息
     SoapObject result = (SoapObject) envelope.bodyIn;
     SoapObject detail = (SoapObject) result.getProperty(
      methodName + "Result");
     // 解析服务器响应的SOAP消息。
     return parseProvinceOrCity(detail);
    }
    return null;
   }
  });
  new Thread(task).start();
  try
  {
   return task.get();
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
  return null;
 }

 // 根据省份获取城市列表
 public static List<String> getCityListByProvince(String province)
 {
  // 调用的方法
  final String methodName = "getSupportCityString";
  // 创建HttpTransportSE传输对象
  final HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
  ht.debug = true;
  // 实例化SoapObject对象
  SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
  // 添加一个请求参数
  soapObject.addProperty("theRegionCode", province);
  // 使用SOAP1.1协议创建Envelop对象
  final SoapSerializationEnvelope envelope =
   new SoapSerializationEnvelope(SoapEnvelope.VER11);
  envelope.bodyOut = soapObject;
  // 设置与.Net提供的Web Service保持较好的兼容性
  envelope.dotNet = true;
  FutureTask<List<String>> task = new FutureTask<List<String>>(
  new Callable<List<String>>()
  {
   @Override
   public List<String> call()
    throws Exception
   {
    // 调用Web Service
    ht.call(SERVICE_NS + methodName, envelope);
    if (envelope.getResponse() != null)
    {
     // 获取服务器响应返回的SOAP消息
     SoapObject result = (SoapObject) envelope.bodyIn;
     SoapObject detail = (SoapObject) result.getProperty(
      methodName + "Result");
     // 解析服务器响应的SOAP消息。
     return parseProvinceOrCity(detail);
    }
    return null;
   }
  });
  new Thread(task).start();
  try
  {
   return task.get();
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
  return null;
 }

 private static List<String> parseProvinceOrCity(SoapObject detail)
 {
  ArrayList<String> result = new ArrayList<String>();
  for (int i = 0; i < detail.getPropertyCount(); i++)
  {
   // 解析出每个省份
   result.add(detail.getProperty(i).toString().split(",")[0]);
  }
  return result;
 }

 public static SoapObject getWeatherByCity(String cityName)
 {
  final String methodName = "getWeather";
  final HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
  ht.debug = true;
  final SoapSerializationEnvelope envelope =
   new SoapSerializationEnvelope(SoapEnvelope.VER11);
  SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
  soapObject.addProperty("theCityCode", cityName);
  envelope.bodyOut = soapObject;
  // 设置与.Net提供的Web Service保持较好的兼容性
  envelope.dotNet = true;
  FutureTask<SoapObject> task = new FutureTask<SoapObject>(
  new Callable<SoapObject>()
  {
   @Override
   public SoapObject call()
    throws Exception
   {
    ht.call(SERVICE_NS + methodName, envelope);
    SoapObject result = (SoapObject) envelope.bodyIn;
    SoapObject detail = (SoapObject) result.getProperty(
     methodName + "Result");
    return detail;
   }
  });
  new Thread(task).start();
  try
  {
   return task.get();
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
  return null;
 }
}


public class MyWeather extends Activity
{
 private Spinner provinceSpinner;
 private Spinner citySpinner;
 private ImageView todayWhIcon1;
 private ImageView todayWhIcon2;
 private TextView textWeatherToday;
 private ImageView tomorrowWhIcon1;
 private ImageView tomorrowWhIcon2;
 private TextView textWeatherTomorrow;
 private ImageView afterdayWhIcon1;
 private ImageView afterdayWhIcon2;
 private TextView textWeatherAfterday;
 private TextView textWeatherCurrent;

 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  todayWhIcon1 = (ImageView) findViewById(R.id.todayWhIcon1);
  todayWhIcon2 = (ImageView) findViewById(R.id.todayWhIcon2);
  textWeatherToday = (TextView) findViewById(R.id.weatherToday);
  tomorrowWhIcon1 = (ImageView) findViewById(R.id.tomorrowWhIcon1);
  tomorrowWhIcon2 = (ImageView) findViewById(R.id.tomorrowWhIcon2);
  textWeatherTomorrow = (TextView) findViewById(R.id.weatherTomorrow);
  afterdayWhIcon1 = (ImageView) findViewById(R.id.afterdayWhIcon1);
  afterdayWhIcon2 = (ImageView) findViewById(R.id.afterdayWhIcon2);
  textWeatherAfterday = (TextView) findViewById(R.id.weatherAfterday);
  textWeatherCurrent = (TextView) findViewById(R.id.weatherCurrent);

  // 获取程序界面中选择省份、城市的Spinner组件
  provinceSpinner = (Spinner) findViewById(R.id.province);
  citySpinner = (Spinner) findViewById(R.id.city);
  // 调用远程Web Service获取省份列表
  List<String> provinces = WebServiceUtil.getProvinceList();
  ListAdapter adapter = new ListAdapter(this, provinces);
  // 使用Spinner显示省份列表
  provinceSpinner.setAdapter(adapter);
  // 当省份Spinner的选择项被改变时
  provinceSpinner.setOnItemSelectedListener(new OnItemSelectedListener()
  {
   @Override
   public void onItemSelected(AdapterView<?> source, View parent,
    int position, long id)
   {
    List<String> cities = WebServiceUtil
     .getCityListByProvince(provinceSpinner.getSelectedItem()
      .toString());
    ListAdapter cityAdapter = new ListAdapter(MyWeather.this,
     cities);
    // 使用Spinner显示城市列表
    citySpinner.setAdapter(cityAdapter);
   }

   @Override
   public void onNothingSelected(AdapterView<?> arg0)
   {
   }
  });
  // 当城市Spinner的选择项被改变时
  citySpinner.setOnItemSelectedListener(new OnItemSelectedListener()
  {
   @Override
   public void onItemSelected(AdapterView<?> source, View parent,
    int position, long id)
   {
    showWeather(citySpinner.getSelectedItem().toString());
   }

   @Override
   public void onNothingSelected(AdapterView<?> arg0)
   {
   }
  });
 }

 private void showWeather(String city)
 {
  String weatherToday = null;
  String weatherTomorrow = null;
  String weatherAfterday = null;
  String weatherCurrent = null;
  int iconToday[] = new int[2];
  int iconTomorrow[] = new int[2];
  int iconAfterday[] = new int[2];
  // 获取远程Web Service返回的对象
  SoapObject detail = WebServiceUtil.getWeatherByCity(city);
  // 获取天气实况
  weatherCurrent = detail.getProperty(4).toString();
  // 解析今天的天气情况
  String date = detail.getProperty(7).toString();
  weatherToday = "今天:" + date.split(" ")[0];
  weatherToday = weatherToday + "\n天气:" + date.split(" ")[1];
  weatherToday = weatherToday + "\n气温:"
   + detail.getProperty(8).toString();
  weatherToday = weatherToday + "\n风力:"
   + detail.getProperty(9).toString() + "\n";
  iconToday[0] = parseIcon(detail.getProperty(10).toString());
  iconToday[1] = parseIcon(detail.getProperty(11).toString());
  // 解析明天的天气情况
  date = detail.getProperty(12).toString();
  weatherTomorrow = "明天:" + date.split(" ")[0];
  weatherTomorrow = weatherTomorrow + "\n天气:" + date.split(" ")[1];
  weatherTomorrow = weatherTomorrow + "\n气温:"
   + detail.getProperty(13).toString();
  weatherTomorrow = weatherTomorrow + "\n风力:"
   + detail.getProperty(14).toString() + "\n";
  iconTomorrow[0] = parseIcon(detail.getProperty(15).toString());
  iconTomorrow[1] = parseIcon(detail.getProperty(16).toString());
  // 解析后天的天气情况
  date = detail.getProperty(17).toString();
  weatherAfterday = "后天:" + date.split(" ")[0];
  weatherAfterday = weatherAfterday + "\n天气:" + date.split(" ")[1];
  weatherAfterday = weatherAfterday + "\n气温:"
   + detail.getProperty(18).toString();
  weatherAfterday = weatherAfterday + "\n风力:"
   + detail.getProperty(19).toString() + "\n";
  iconAfterday[0] = parseIcon(detail.getProperty(20).toString());
  iconAfterday[1] = parseIcon(detail.getProperty(21).toString());
  // 更新当天的天气实况
  textWeatherCurrent.setText(weatherCurrent);
  // 更新显示今天天气的图标和文本框
  textWeatherToday.setText(weatherToday);
  todayWhIcon1.setImageResource(iconToday[0]);
  todayWhIcon2.setImageResource(iconToday[1]);
  // 更新显示明天天气的图标和文本框
  textWeatherTomorrow.setText(weatherTomorrow);
  tomorrowWhIcon1.setImageResource(iconTomorrow[0]);
  tomorrowWhIcon2.setImageResource(iconTomorrow[1]);
  // 更新显示后天天气的图标和文本框
  textWeatherAfterday.setText(weatherAfterday);
  afterdayWhIcon1.setImageResource(iconAfterday[0]);
  afterdayWhIcon2.setImageResource(iconAfterday[1]);
 }

 // 工具方法,该方法负责把返回的天气图标字符串,转换为程序的图片资源ID。
 private int parseIcon(String strIcon)
 {
  if (strIcon == null)
   return -1;
  if ("0.gif".equals(strIcon))
   return R.drawable.a_0;
  if ("1.gif".equals(strIcon))
   return R.drawable.a_1;
  if ("2.gif".equals(strIcon))
   return R.drawable.a_2;
  if ("3.gif".equals(strIcon))
   return R.drawable.a_3;
  if ("4.gif".equals(strIcon))
   return R.drawable.a_4;
  if ("5.gif".equals(strIcon))
   return R.drawable.a_5;
  if ("6.gif".equals(strIcon))
   return R.drawable.a_6;
  if ("7.gif".equals(strIcon))
   return R.drawable.a_7;
  if ("8.gif".equals(strIcon))
   return R.drawable.a_8;
  if ("9.gif".equals(strIcon))
   return R.drawable.a_9;
  if ("10.gif".equals(strIcon))
   return R.drawable.a_10;
  if ("11.gif".equals(strIcon))
   return R.drawable.a_11;
  if ("12.gif".equals(strIcon))
   return R.drawable.a_12;
  if ("13.gif".equals(strIcon))
   return R.drawable.a_13;
  if ("14.gif".equals(strIcon))
   return R.drawable.a_14;
  if ("15.gif".equals(strIcon))
   return R.drawable.a_15;
  if ("16.gif".equals(strIcon))
   return R.drawable.a_16;
  if ("17.gif".equals(strIcon))
   return R.drawable.a_17;
  if ("18.gif".equals(strIcon))
   return R.drawable.a_18;
  if ("19.gif".equals(strIcon))
   return R.drawable.a_19;
  if ("20.gif".equals(strIcon))
   return R.drawable.a_20;
  if ("21.gif".equals(strIcon))
   return R.drawable.a_21;
  if ("22.gif".equals(strIcon))
   return R.drawable.a_22;
  if ("23.gif".equals(strIcon))
   return R.drawable.a_23;
  if ("24.gif".equals(strIcon))
   return R.drawable.a_24;
  if ("25.gif".equals(strIcon))
   return R.drawable.a_25;
  if ("26.gif".equals(strIcon))
   return R.drawable.a_26;
  if ("27.gif".equals(strIcon))
   return R.drawable.a_27;
  if ("28.gif".equals(strIcon))
   return R.drawable.a_28;
  if ("29.gif".equals(strIcon))
   return R.drawable.a_29;
  if ("30.gif".equals(strIcon))
   return R.drawable.a_30;
  if ("31.gif".equals(strIcon))
   return R.drawable.a_31;
  return 0;
 }
}

 


public class ListAdapter extends BaseAdapter
{
 private Context context;
 private List<String> values;

 public ListAdapter(Context context , List<String> values)
 {
  this.context = context;
  this.values = values;
 }

 @Override
 public int getCount()
 {
  return values.size();
 }

 @Override
 public Object getItem(int position)
 {
  return values.get(position);
 }

 @Override
 public long getItemId(int position)
 {
  return position;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent)
 {
  TextView text = new TextView(context);
  text.setText(values.get(position));
  text.setTextSize(20);
  text.setTextColor(Color.WHITE);
  return text;
 }
}

上面的Activity代码已经不再涉及及调用Web Service的代码了,只是简单的调用Service操作,解析Web Service返回的SOAP的消息包,并把SOAP小细胞中的数据显示出来,运行该程序,选择指定城市,即可,运行结果如图。从这个应用可以看出来不管运行的Web Service的功能有多么复杂,对于Android客服端而言,他只要通过Web Service获取对方提供的数据,并将这些数据整合到自己的应用中就可以了,因此Web Service为Android提供了强大的后台支持。

        第一次写博客,中间还不能发,很伤。现在终于弄好了,写的不怎么样,希望各位看客多指点,多赐教!

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14844次
    • 积分:326
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:0篇
    • 译文:0篇
    • 评论:19条
    文章分类