当前位置: 代码迷 >> Android >> Android - Earthquake(震灾显示器) 项目 详解
  详细解决方案

Android - Earthquake(震灾显示器) 项目 详解

热度:469   发布时间:2016-04-28 06:26:12.0
Android - Earthquake(地震显示器) 项目 详解

Earthquake(地震显示器) 项目 详解


本文地址: http://blog.csdn.net/caroline_wendy/article/details/21976997


环境: Android Studio 0.5.2, Gradle 1.11, kindle fire

时间: 2014-3-24


Earthquake项目, 主要是读取USGS(United States Geological Survey, 美国地址勘探局)提供的feeds(订阅源), 进行显示数据;

需要读取互联网的数据, 进行格式解析(parse), 数据类型是atom类型, 类似XML.

订阅源地址: http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.atom

格式:

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:georss="http://www.georss.org/georss"><title>USGS Magnitude 2.5+ Earthquakes, Past Day</title><updated>2014-03-24T07:56:39Z</updated><author><name>U.S. Geological Survey</name><uri>http://earthquake.usgs.gov/</uri></author><id>http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.atom</id><link rel="self" href="http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.atom"/><icon>http://earthquake.usgs.gov/favicon.ico</icon><entry><id>urn:earthquake-usgs-gov:ci:15479569</id><title>M 2.9 - 9km W of Alberto Oviedo Mota, Mexico</title><updated>2014-03-24T07:48:34.609Z</updated><link rel="alternate" type="text/html" href="http://earthquake.usgs.gov/earthquakes/eventpage/ci15479569"/><summary type="html"><![CDATA[<p class="quicksummary"><a href="http://earthquake.usgs.gov/earthquakes/eventpage/ci15479569#dyfi" class="mmi-I" title="Did You Feel It? maximum reported intensity (0 reports)">DYFI? - <strong class="roman">I</strong></a></p><dl><dt>Time</dt><dd>2014-03-24 07:38:10 UTC</dd><dd>2014-03-23 23:38:10 -08:00 at epicenter</dd><dt>Location</dt><dd>32.222°N 115.274°W</dd><dt>Depth</dt><dd>14.10 km (8.76 mi)</dd></dl>]]></summary><georss:point>32.2215 -115.274</georss:point><georss:elev>-14100</georss:elev><category label="Age" term="Past Hour"/><category label="Magnitude" term="Magnitude 2"/></entry>............

Earthquake的具体设计:

新建项目: Earthquake


1. 新建Quake(Quake.java)类, 显示地震数据.

位置: java->package->Quake

package mzx.spike.earthquake.app;import android.location.Location;import java.text.SimpleDateFormat;import java.util.Date;public class Quake {    private Date date;    private String details;    private Location location;    private double magnitude;    private String link;    public Date getDate() { return date; }    public String getDetails() { return details; }    public Location getLocation() { return location; }    public double getMagnitude() { return magnitude; }    public String getLink() { return link; }    public Quake(Date _d, String _det, Location _loc, double _mag, String _link) {        date = _d;        details = _det;        location = _loc;        magnitude = _mag;        link = _link;    }    @Override    public String toString() {        SimpleDateFormat sdf = new SimpleDateFormat("HH.mm");        String dateString = sdf.format(date);        return dateString + ": " + magnitude + " " + details;    }}

详解:

1. 显示的类型: date, 日期; details, 详细信息, 地点; location, 位置; magnitude, 震级; link, 链接;

2. get()方法, 返回信息; 构造函数, 赋初值; toString(), 默认输出信息;


2. 修改activity_main.xml, 添加fragment.

位置: res->layout->activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:paddingBottom="@dimen/activity_vertical_margin"    tools:context="mzx.spike.earthquake.app.MainActivity">    <fragment android:name="mzx.spike.earthquake.app.EarthquakeListFragment"        android:id="@+id/EarthquakeListFragment"        android:layout_width="match_parent"        android:layout_height="match_parent"    /></RelativeLayout>

添加Fragment, 指定实现(.java)文件位置.


3. 新建EarthquakeListFragment.java

位置: java->package->EarthquakeListFragment.java

package mzx.spike.earthquake.app;import android.app.ListFragment;import android.location.Location;import android.os.Bundle;import android.os.Handler;import android.util.Log;import android.widget.ArrayAdapter;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.GregorianCalendar;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;public class EarthquakeListFragment extends ListFragment {    ArrayAdapter<Quake> aa;    ArrayList<Quake> earthquakes = new ArrayList<Quake>();    @Override    public void onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        int layoutID = android.R.layout.simple_list_item_1;        aa = new ArrayAdapter<Quake>(getActivity(), layoutID , earthquakes);        setListAdapter(aa);        Thread t = new Thread(new Runnable() {            @Override            public void run() {                refreshEarthquakes();            }        });        t.start();    }    private static final String TAG = "EARTHQUAKE";    private Handler handler = new Handler();    private void refreshEarthquakes() {        // Get the XML        URL url;        try {            String quakeFeed = getString(R.string.quake_feed);            url = new URL(quakeFeed);            URLConnection connection;            connection = url.openConnection();            HttpURLConnection httpConnection = (HttpURLConnection)connection;            int responseCode = httpConnection.getResponseCode();            if (responseCode == HttpURLConnection.HTTP_OK) {                InputStream in = httpConnection.getInputStream();                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();                DocumentBuilder db = dbf.newDocumentBuilder();                // Parse the earthquake feed.                Document dom = db.parse(in);                Element docEle = dom.getDocumentElement();                // Clear the old earthquakes                earthquakes.clear();                // Get a list of each earthquake entry.                NodeList nl = docEle.getElementsByTagName("entry");                if (nl != null && nl.getLength() > 0) {                    for (int i = 0 ; i < nl.getLength(); i++) {                        Element entry = (Element)nl.item(i);                        Element title = (Element)entry.getElementsByTagName("title").item(0);                        Element g = (Element)entry.getElementsByTagName("georss:point").item(0);                        Element when = (Element)entry.getElementsByTagName("updated").item(0);                        Element link = (Element)entry.getElementsByTagName("link").item(0);                        String details = title.getFirstChild().getNodeValue();                        String hostname = "http://earthquake.usgs.gov";                        String linkString = hostname + link.getAttribute("href");                        String point = g.getFirstChild().getNodeValue();                        String dt = when.getFirstChild().getNodeValue();                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'");                        Date qdate = new GregorianCalendar(0,0,0).getTime();                        try {                           qdate = sdf.parse(dt);                        } catch (ParseException e) {                            Log.d(TAG, "Date parsing exception.", e);                        }                        String[] location = point.split(" ");                        Location l = new Location("dummyGPS");                        l.setLatitude(Double.parseDouble(location[0]));                        l.setLongitude(Double.parseDouble(location[1]));                        String magnitudeString = details.split(" ")[1];                        int end =  magnitudeString.length()-1;                        double magnitude = Double.parseDouble(magnitudeString.substring(0, end));                        details = details.split(",")[1].trim();                        final Quake quake = new Quake(qdate, details, l, magnitude, linkString);                        // Process a newly found earthquake                        handler.post(new Runnable() {                            @Override                            public void run() {                                addNewQuake(quake);                            }                        });                    }                }            }        } catch (MalformedURLException e) {            Log.d(TAG, "MalformedURLException", e);        } catch (IOException e) {            Log.d(TAG, "IOException", e);        } catch (ParserConfigurationException e) {            Log.d(TAG, "Parser Configuration Exception", e);        } catch (SAXException e) {            Log.d(TAG, "SAX Exception", e);        }        finally {        }    }    private void addNewQuake(Quake _quake) {        // Add the new quake to our list of earthquakes.        earthquakes.add(_quake);        // Notify the array adapter of a change.        aa.notifyDataSetChanged();    }}

详解:

1. 重写onActivityCreated()方法, 绑定适配器, 在线程(thread)中刷新地震信息(refreshEarthquakes);

2. 刷新地震信息refreshEarthquakes()方法, 根据订阅源(feed), 创建HTTP链接;

3. 解析文档(parse), 清空数据(clear);

4. 解析atom格式的标签, 根据标签属性, 输出相应的信息;

5. 实例化(new)Quake类, 在handler(句柄)中, 运行添加地震信息的方法(addNewQuake);

6. 注意链接需要相应的异常捕获(catch)方式, 否则报错;

7. 网络调用(network call)在主Activity调用, 会报错, 需要在线程,后台(asynctask)运行;

8. Handler会产生歧义, 注意使用Android的相应类, 不是java的, 否则无法实例化(initialized)

9. 日期格式(SimpleDateFormat)解析, 需要匹配相应的字符串, 否则抛出异常, 无法解析(parse);

10 添加新的地震信息(addNewQuake), 通知适配器(notifyDataSetChanged), 进行改变.


4. 修改strings信息

位置: res->values->strings

<?xml version="1.0" encoding="utf-8"?><resources>    <string name="app_name">Earthquake</string>    <string name="hello_world">Hello world!</string>    <string name="action_settings">Settings</string>    <string name="quake_feed">http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.atom</string></resources>

添加相应的订阅源(feeds).


5. 修改AndroidManifest.xml

位置: root->AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="mzx.spike.earthquake.app" >    <uses-permission android:name="android.permission.INTERNET"/>    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="mzx.spike.earthquake.app.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

提供网络访问权限(permission), <uses-permission android:name="android.permission.INTERNET"/>.


6. 运行程序.


下载地址: http://download.csdn.net/detail/u012515223/7091879





  相关解决方案