目录
引言:
因为本人在做这个天气预报的时候,遭遇了不少挫折,一直无法通过webservices去访问天气,后来看到返回语句有说是注册一个webservices的账号就行,但不知为何,我一直无法注册成功,明明在测试里头,没有填注册信息也是可以直接访问。再然后找到一个说是免费的一个getWeatherbyCityName,结果也一直不得其法。所以最后做出来这个项目后,决定将这个做好的项目发出来,与大家一起学习!一定要配置好网络权限哈!!!
1.该项目的实现效果
2.activity_main.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/b1"
android:gravity="center"
android:textSize="22dp"
android:textColor="@color/black"
android:backgroundTint="@color/hui"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.394"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.124" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/b2"
android:textColor="@color/black"
android:gravity="center"
android:textSize="22dp"
android:backgroundTint="@color/hui"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.69"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.124" />
<EditText
android:id="@+id/edit"
android:layout_width="330dp"
android:layout_height="500dp"
android:ems="10"
android:hint="Small text"
android:textColorHint="@color/black"
android:gravity="start|top"
android:inputType="textMultiLine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.MainActivity.java代码:
package com.example.weather;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private Button b1;
private Button b2;
private TextView t1;
private String result;
private EditText e1;
String a;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1=findViewById(R.id.button);
b2=findViewById(R.id.button2);
e1=findViewById(R.id.edit);
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
a=b1.getText().toString().trim();
//启动后台异步线程进行连接webService操作,并且根据返回结果在主线程中改变UI
QueryAddressTask queryAddressTask = new QueryAddressTask();
//启动后台任务
queryAddressTask.execute();
}
});
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
a=b2.getText().toString().trim();
//启动后台异步线程进行连接webService操作,并且根据返回结果在主线程中改变UI
QueryAddressTask queryAddressTask = new QueryAddressTask();
//启动后台任务
queryAddressTask.execute();
}
});
}
public static String getWeather(String city) {
try {
Document doc;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
//输入要查询的地名
InputStream is = getSoapInputStream(city);
doc = db.parse(is);
NodeList nl = doc.getElementsByTagName("string");
StringBuffer sb = new StringBuffer();
for (int count = 0; count < nl.getLength(); count++) {
Node n = nl.item(count);
if(n.getFirstChild().getNodeValue().equals("查询结果为空!")) {
sb = new StringBuffer("") ;
break ;
}
sb.append(n.getFirstChild().getNodeValue() + "\n");
}
is.close();
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static InputStream getSoapInputStream(String city) throws Exception {
try {
//执行网页查询操作啦!
String soap = getSoapRequest(city);
if (soap == null) {
return null;
}
URL url = new URL(
"http://www.webxml.com.cn/WebServices/WeatherWS.asmx");
URLConnection conn = url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
//差点被坑了!!!
// conn.setRequestProperty("Content-Length", Integer.toString(soap
// .length()));
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
conn.setRequestProperty("SOAPAction",
"http://WebXml.com.cn/getWeather");
OutputStream os = conn.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8");
osw.write(soap);
osw.flush();
osw.close();
InputStream is = conn.getInputStream();
return is;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static String getSoapRequest(String city) {
StringBuilder sb = new StringBuilder();
sb.append("<?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> <getWeather xmlns=\"http://WebXml.com.cn/\">"
+ "<theCityCode>" + city
+ "</theCityCode> </getWeather>"
+ "</soap:Body></soap:Envelope>");
return sb.toString();
}
String result1;
//执行这些还是得在异步线程里呀,小心翻车
class QueryAddressTask extends AsyncTask<Void,Integer,Boolean>{
@Override
protected Boolean doInBackground(Void... voids) {
result1 = getWeather(a); //在子线程中请求webservice
return null;
}
@Override
protected void onPostExecute(Boolean aBoolean) {
StringBuilder builder = new StringBuilder();
e1.setText(result1);
//Toast.makeText(MainActivity.this, result1, Toast.LENGTH_SHORT).show();
}
}
}
4.关于开启网络权限的方法:
具体可以参考一下我上一篇文章和所用到的api:(2条消息) Android Studio之号码归属地查询(Webservice)_芒心008的博客-CSDN博客
因为api不同开启网络权限的方法有些许不同,如果一直不得其法,建议换个api再运行,有不懂的欢迎留言!