android怎么访问天气webservice,用网上找的链接都不行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android怎么访问天气webservice,用网上找的链接都不行相关的知识,希望对你有一定的参考价值。

首先将省市信息以的形式保存到名为arrays.xml的文件中(我记得貌似一定要把文件名取为arrays.xml)。其中,name属性可以理解为数组名和ID名。这里要注意:省份的顺序要与对应拥有的城市顺序一致。即台湾为最后最后一个省,

在选择城市界面对应的Activity中,通过下面代码将省份列表显示。其中R.array.provinces就是我们上面定义的name属性值。

ArrayAdapter adapter =
ArrayAdapter.createFromResource(this,R.array.provinces,android.R.layout.simple_spinner_item);

provinceSpinner.setAdapter(adapter);

接着,对省份下拉列表进行监听。这里有一个比较麻烦的地方,因为当你选择不同的省份的时候,需要显示该省份对应的城市。面对那么多的省份,如果我们通过if或者switch来操作的话,使得代码很冗长,也难以维护。发现这里是通过R.array.name这种形式来显示下拉列内容的。通过观察R文件,发现了一定的规律。R文件中的array类的int属性值,是根据写入顺序,从0x7f050000开始,逐个+1形成的。即

public static final int provinces=0x7f050000;

public static final int beijing_array=0x7f050001;

public static final int tianjin_array=0x7f050002;

可能R文件中没有按照此顺序排列,不过,不影响这一性质。所以我就想到了只要城市数组的顺序与省份一一对应(上面提到过),就可以通过所选省份的position,跟ID初始值
0x7f050000相加,得出所属城市的数组。具体看看代码

provinceSpinner.setOnItemSelectedListener(new OnItemSelectedListener()


public void onItemSelected(AdapterView parent, View view,

int position, long id)

if(position != 0)//选择了省份,position=0时,为“--请选择--”

*0x7f050000为R文件中省份数组对应的id值,只要加上position,即可获得对应选项(省份)的城市

*/

int cityID = 0x7f050000 + position;

ArrayAdapter adapter =
ArrayAdapter.createFromResource(getApplicationContext(), cityID,
android.R.layout.simple_spinner_item);

citySpinner.setAdapter(adapter);





public void onNothingSelected(AdapterView parent)



);

二。

三、SQLite保存城市数据

使用SQLite而不使用Intent传递参数,是因为当用户下次打开程序时,当前城市应该为TA最后一次的选择。关于SQLite的使用,网上有很多文章,比如:52android.blog.51cto.com/2554429/478368
之前也学习过一些,但四、PreferenceActivity作为设置界面

参照Android系统的设置,用PreferenceActivity来对系统进行信息配置和管理。这里我也采用PreferenceActivity作为设置界面。(上方图三)

首先,编写xml文件。PreferenceCategory:类别(用于分组)。key:唯一标识(获取信息时使用)。title:显示标题。summary:小标题。还有defaultValue:默认值。我这里值用到了CheckBoxPreference,它还有EditTextPreperence,RingtonePreference,ListPreference,Preference等。

schemas.android.com/apk/res/android" >

android:key="threeDay"

android:summary="今明后三天的天气预报,如果不选,则只有当天的天气"

android:title="三天预报" />

android:key="cityInfo"

android:summary="关于当前城市的简要介绍"

android:title="城市简介" />

然后,新建Activity继承 PreferenceActivity
,重写onCreate方法,通过addPreferencesFromResource(R.xml.xx); 加载Preference。

?

public class SetupActivity extends PreferenceActivity

@Override

protected void onCreate(Bundle savedInstanceState)

super.onCreate(savedInstanceState);

addPreferencesFromResource(R.xml.setup);





最后,获取preference数据。可 通过下面三种方式:

1、getPreferences():可以获取同一activity中的preference;

2、getSharedPreferences():可以获取应用级别的preferences,即封装在同一app中,使用SharePreferences
prefs = getSharedPreferences(packName+name ,0)

3、getDefaultSharedPreferences():通过Android的管理器来获取其所管理的preferences。

由于这里不是同一个Activity,所以不能使用getPreferences()。我这里只有一个preference,因此使用PreferenceManager.getDefaultSharedPreferences(this);来获取较方便。

五、通过WebService获取天气信息

WebService获取天气的网址为:webxml.com.cn/webservices/weatherwebservice.asmx上面

// 保存获取到的信息

SoapObject detail = null;

// 1.实例化SoapObject对象

SoapObject soapObject = new SoapObject(NAMESPACE, METHOD_NAME);

// 2.如果方法需要参数,设置参数

soapObject.addProperty("theCityName", cityName);

// 3.设置Soap的请求信息,获得序列化envelope,参数部分为Soap协议的版本号

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(

SoapEnvelope.VER11);

envelope.bodyOut = soapObject;

envelope.dotNet = true;

envelope.setOutputSoapObject(soapObject);

// 4.构建传输对象

int timeout = 10000;// 设置超时为10秒

MyAndroidHttpTransport httpTransportSE = new MyAndroidHttpTransport(URL,
timeout);

httpTransportSE.debug = true;

// 5.访问WebService,第一个参数为命名空间 + 方法名,第二个参数为Envelope对象

httpTransportSE.call(SOAP_ACTION, envelope);

detail = (SoapObject) envelope.getResponse();// 获取详细天气信息

if (detail != null) // 当前城市有天气信息

return parseWeather(detail);//解析天气



这里要注意一下,代码18行
MyAndroidHttpTransport为继承了HttpTransportSE的内部类。虽然ksoap2版本中的HttpTransportSE已经可以设置timeout(超时时间),但是运行后发现没有效果。查找资料后,才知道HttpTransportSE的源码中并没有把timeout作为参数传递给ServiceConnectionSE。因此我们需要创建一个类,使得timeout起作用。

class MyAndroidHttpTransport extends HttpTransportSE

private int timeout = 20000; // 默认超时时间为20s

public MyAndroidHttpTransport(String url)

super(url);



public MyAndroidHttpTransport(String url, int timeout)

super(url);

this.timeout = timeout;



//此方法使得超时有效

public ServiceConnection getServiceConnection() throws IOException

ServiceConnectionSE serviceConnection = new
ServiceConnectionSE(this.url,timeout);

return serviceConnection;





现在来说创建service的过程

1、新建类继承Service;

2、必须重写onBind方法(如果你通过bindService方法启动service,则在这个方法内执行操作)

3、重写onStart方法(由于本程序中,每次点击查询按钮,service就要进行联网操作,因此我通过startService方法启动service,则每次startService,都会执行onStart方法。注意:在service停止前,onCreate只会执行一次)

4、在AndroidManifest.xml文件中添加

className为类名全称:如vaint.wyt
.service.WeatherService。如果跟MainActivity在同一个包,可以直接写 .WeatherService。

serviceName为startService(new Intent(String
action))的action,bindService类似。

5、在需要启动service的地方,添加一下代码

Intent intent =new Intent("WeatherService");

//传递数据,可以由onStart接收

intent.putExtra("city", city);

this.startService(intent);

6、如果是通过bindService启动service,则可以不执行unbindService。因为只要程序退出,service也将被摧毁。但是,如果是通过startService启动service,则必须通过stopService将其停止,否则即使程序退出,service依旧在运行。我们可以在MainActivity的onDestroy中执行stopService。

protected void onDestroy()

//停止service

stopService(new Intent("WeatherService"));

super.onDestroy();



七、用BroadcastReceiver实现从service到Activity的通信

这只是其中一种方法而已。

1、创建广播接收器。(可以直接在MainActivity中作为内部类创建)重写onReceive方法,接收从service传递过来的天气信息。

//定义一个广播接收器,用于接收Service获得的天气信息

class MyBroadcastRecever extends BroadcastReceiver

@Override

public void onReceive(Context context, Intent intent)

String[] weatherInfo = intent.getStringArrayExtra("weather");

if(weatherInfo==null)

Toast.makeText(MainActivity.this, "没有当前城市的天气信息", 1000).show();

else if(weatherInfo.length==1)//即weatherInfo = new
String[]"timeOut";

Toast.makeText(MainActivity.this, "连接超时,请检查网络", 1000).show();

else

showWeather(weatherInfo);







2、通过代码动态注册广播接收器。(也可以在AndroidManifest中添加属性 )

//注册广播接收器

IntentFilter filter = new IntentFilter();

myBroadcastRecever = new MyBroadcastRecever();

//设置接收广播的类型,这里要和Service里设置的类型匹配,还可以在AndroidManifest.xml文件中注册

//BROADCAST_ACTION=“某个自定义字符串”。如果有多个广播,则要唯一

filter.addAction(BROADCAST_ACTION);

registerReceiver(myBroadcastRecever, filter);

3、通过广播发送消息

Intent i = new Intent();

i.putExtra("weather", weather);

//BROADCAST_ACTION与注册时的字符串一致

i.setAction(BROADCAST_ACTION);

sendBroadcast(i);
参考技术A WebService是一种基于SOAP协议的远程调用标准,通过webservice可以将不同操作系统平台、不同语言、不同技术整合到一块。在Android SDK中并没有提供调用WebService的库,因此,需要使用第三方的SDK来调用WebService。PC版本的WEbservice客户端库非常丰富,例如Axis2,CXF等,但这些开发包对于Android系统过于庞大,也未必很容易移植到Android系统中。因此,这些开发包并不是在我们的考虑范围内。适合手机的WebService客户端的SDK有一些,比较常用的有Ksoap2,可以从http://code.google.com/p/ksoap2-android/downloads/list进行下载;将下载的ksoap2-android-assembly-2.4-jar-with-dependencies.jar包复制到Eclipse工程的lib目录中,当然也可以放在其他的目录里。同时在Eclipse工程中引用这个jar包。
具体调用调用webservice的方法为:
(1) 指定webservice的命名空间和调用的方法名,如:
SoapObject request =new SoapObject(http://service,”getName”);
SoapObject类的第一个参数表示WebService的命名空间,可以从WSDL文档中找到WebService的命名空间。第二个参数表示要调用的WebService方法名。
(2) 设置调用方法的参数值,如果没有参数,可以省略,设置方法的参数值的代码如下:
Request.addProperty(“param1”,”value”);
Request.addProperty(“param2”,”value”);
要注意的是,addProperty方法的第1个参数虽然表示调用方法的参数名,但该参数值并不一定与服务端的WebService类中的方法参数名一致,只要设置参数的顺序一致即可。
(3) 生成调用Webservice方法的SOAP请求信息。该信息由SoapSerializationEnvelope对象描述,代码为:
SoapSerializationEnvelope envelope=new
SoapSerializationEnvelope(SoapEnvelope.VER11);
Envelope.bodyOut = request;
创建SoapSerializationEnvelope对象时需要通过SoapSerializationEnvelope类的构造方法设置SOAP协议的版本号。该版本号需要根据服务端WebService的版本号设置。在创建SoapSerializationEnvelope对象后,不要忘了设置SOAPSoapSerializationEnvelope类的bodyOut属性,该属性的值就是在第一步创建的SoapObject对象。
(4) 创建HttpTransportsSE对象。通过HttpTransportsSE类的构造方法可以指定WebService的WSDL文档的URL:
HttpTransportSE ht=new HttpTransportSE(“http://192.168.18.17:80
/axis2/service/SearchNewsService?wsdl”);
(5)使用call方法调用WebService方法,代码:
ht.call(null,envelope);
Call方法的第一个参数一般为null,第2个参数就是在第3步创建的SoapSerializationEnvelope对象。
(6)使用getResponse方法获得WebService方法的返回结果,代码:
SoapObject soapObject =( SoapObject) envelope.getResponse();
以下为简单的实现一个天气查看功能的例子:

publicclass WebService extends Activity
privatestaticfinal String NAMESPACE ="http://WebXml.com.cn/";
// WebService地址
privatestatic String URL ="http://www.webxml.com.cn/
webservices/weatherwebservice.asmx";
privatestaticfinal String METHOD_NAME ="getWeatherbyCityName";
privatestatic String SOAP_ACTION ="http://WebXml.com.cn/
getWeatherbyCityName";

private String weatherToday;

private Button okButton;
private SoapObject detail;

@Override
publicvoid onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
okButton = (Button) findViewById(R.id.ok);

okButton.setOnClickListener(new Button.OnClickListener()
publicvoid onClick(View v)
showWeather();

);


privatevoid showWeather()
String city ="武汉";
getWeather(city);


@SuppressWarnings("deprecation")
publicvoid getWeather(String cityName)
try
System.out.println("rpc------");
SoapObject rpc =new SoapObject(NAMESPACE, METHOD_NAME);
System.out.println("rpc"+ rpc);
System.out.println("cityName is "+ cityName);
rpc.addProperty("theCityName", cityName);

AndroidHttpTransport ht =new AndroidHttpTransport(URL);
ht.debug =true;

SoapSerializationEnvelope envelope =new SoapSerializationEnvelope(
SoapEnvelope.VER11);

envelope.bodyOut = rpc;
envelope.dotNet =true;
envelope.setOutputSoapObject(rpc);

ht.call(SOAP_ACTION, envelope);

SoapObject result = (SoapObject) envelope.bodyIn;
detail = (SoapObject) result
.getProperty("getWeatherbyCityNameResult");

System.out.println("result"+ result);
System.out.println("detail"+ detail);
Toast.makeText(WebService.this, detail.toString(),
Toast.LENGTH_LONG).show();
parseWeather(detail);

return;
catch (Exception e)
e.printStackTrace();



privatevoid parseWeather(SoapObject detail)
throws UnsupportedEncodingException
String date = detail.getProperty(6).toString();
weatherToday ="今天:"+ date.split("")[0];
weatherToday = weatherToday +"\n天气:"+ date.split("")[1];
weatherToday = weatherToday +"\n气温:"
+ detail.getProperty(5).toString();
weatherToday = weatherToday +"\n风力:"
+ detail.getProperty(7).toString() +"\n";
System.out.println("weatherToday is "+ weatherToday);
Toast.makeText(WebService.this, weatherToday,
Toast.LENGTH_LONG).show();


参考技术B 请注意:
检查2点:
1、<uses-permission android:name="android.permission.INTERNET"/>
2、目标设备有无连接到网络:比如WiFi或这个移动网络。本回答被提问者和网友采纳

以上是关于android怎么访问天气webservice,用网上找的链接都不行的主要内容,如果未能解决你的问题,请参考以下文章

怎么根据中国气象局提供的接口做一个自己的天气预报(.Net)

C#用天气预报的WebServices

如何在网页中插入可更新的天气预报代码

利用java webservice调用天气预报实践

webservice接口,用Soapui

BIRT 怎么调用 Webservice 作为数据源