接下来的例子,你将要创建一个使用USGS地震种子来显示最近地震列表的工具。

你将数次回到这个地震应用程序,第一次是在第6章中的用一个Content Provider保存和共享地震数据,再一次是在第7章和第8章中,添加映射支持和在后台服务中更新地震数据。

在这个例子中,你将要创建一个基于List的Activity,它连向一个地震种子,并显示位置、等级以及地震的时间。另外,你还将使用一个AlertDialog来提供一个细节的窗口,包含一个链向USGS站点的可链接TextView。

1. 创建一个地震工程,包含一个Earthquake Activity。修改main.xml layout资源包含一个ListView控件——确保要命名它,因为在Activity的代码中你要引用它。

<?xml version=”1.0” encoding=”utf-8”?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”vertical”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”>

<ListView

android:id=”@+id/earthquakeListView”

android:layout_width=”fill_parent”

android:layout_height=”wrap_content”

/>

</LinearLayout>

2. 创建一个新的Quake公共类。这个类用于储存每个地震的细节(时间,细节,位置,等级和链接等)。重写toString方法来提供在ListView中使用的每个Quake的字符串。

package com.paad.earthquake;

import java.util.Date;

import java.text.SimpleDateFormat;

import android.location.Location;

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;

}

}

3. 在Earthquake Activity里,重写onCreate方法来储存一个Quake对象的ArrayList,并使用一个ArrayAdapter绑定其到ListView上。

package com.paad.earthquake;

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;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

import android.app.Activity;

import android.app.Dialog;

import android.location.Location;

import android.os.Bundle;

import android.view.Menu;

import android.view.View;

import android.view.WindowManager;

import android.view.MenuItem;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.AdapterView.OnItemClickListener;

public class Earthquake extends Activity {

ListView earthquakeListView;

ArrayAdapter<Quake> aa;

ArrayList<Quake> earthquakes = new ArrayList<Quake>();

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

earthquakeListView =(ListView)this.findViewById(R.id.earthquakeListView);

int layoutID = android.R.layout.simple_list_item_1;

aa = new ArrayAdapter<Quake>(this, layoutID , earthquakes);

earthquakeListView.setAdapter(aa);

}

}

4. 接下来,处理地震种子。在这个例子中,使用的种子是1天的USGS种子,并且等级大于2.5级。

以外部字符串资源的方式添加种子的位置。这种方式的优点是对于不同的用户位置来说可以指定不同的种子。

<?xml version=”1.0” encoding=”utf-8”?>

<resources>

<string name=”app_name”>Earthquake</string>

<string name=”quake_feed”>

http://earthquake.usgs.gov/eqcenter/catalogs/1day-M2.5.xml

</string>

</resources>

5. 在你的程序能访问Internet之前,需要授予Internet的权限。在manifest中添加uses-permission节点。

<uses-permission xmlns:android=”http://schemas.android.com/apk/res/android”

android:name=”android.permission.INTERNET”>

</uses-permission>

6. 回到Earthquake Activity中,创建一个新的refreshEarthquakes方法来连接,解析地震种子。提取每个earthquake,并解析细节来获得时间、等级、链接和位置。当你完成每个earthquake的解析,传递它到新的addNewQuake方法中。

XML的解析如下所示,没有太多的解释。

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;

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;

sdf = new SimpleDateFormat(“yyyy-MM-dd’T’hh:mm:ss’Z’”);

Date qdate = new GregorianCalendar(0,0,0).getTime();

try

{

qdate = sdf.parse(dt);

}

catch (ParseException e)

{

e.printStackTrace();

}

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;

magnitude = Double.parseDouble(magnitudeString.substring(0, end));

details = details.split(“,”)[1].trim();

Quake quake = new Quake(qdate, details, l,

magnitude, linkString);

// Process a newly found earthquake

addNewQuake(quake);

}

}

}

}

catch (MalformedURLException e)

{

e.printStackTrace();

}

catch (IOException e)

{

e.printStackTrace();

}

catch (ParserConfigurationException e)

{

e.printStackTrace();

}

catch (SAXException e)

{

e.printStackTrace();

}

finally

{

}

}

private void addNewQuake(Quake _quake) {

// TODO: Add the earthquakes to the array list.

}

7. 更新addNewQuake方法,让它可以带一个刚处理过的Quake参数并将其添加Earthquake的ArrayList中。它还应该通知ArrayAdapter底层数据发生了变化。

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();

}

8. 修改onCreate方法在启动时调用refreshEarthquakes。

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

earthquakeListView =

(ListView)this.findViewById(R.id.earthquakeListView);

int layoutID = android.R.layout.simple_list_item_1;

aa = new ArrayAdapter<Quake>(this, layoutID , earthquakes);

earthquakeListView.setAdapter(aa);

refreshEarthquakes();

}

Internet查询目前发生在UI主线程。这是一种糟糕的方式,当查询需要花费超过几秒的时间时应用程序会变得无响应。在第8章,你将学习如何将这样的耗时的操作移到后台线程中。

9. 如果你运行你的工程,你应该看到一个ListView中显示了过去24小时里等级大于2.5的地震,如图5-6所示。

图5-6

10. 还剩下两步来能你的程序变得更加有用。第一,创建一个菜单项来让用户在需要的时候更新一下地址种子。

10.1 为菜单选择添加外部字符串。

<string name=”menu_update”>Refresh Earthquakes</string>

10.2  然后重写Activity的onCreateOptionsMenu和onOptionsItemSelected方法,来显示和处理菜单项的更新操作。

static final private int MENU_UPDATE = Menu.FIRST;

@Override

public boolean onCreateOptionsMenu(Menu menu) {

super.onCreateOptionsMenu(menu);

menu.add(0, MENU_UPDATE, Menu.NONE, R.string.menu_update);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

super.onOptionsItemSelected(item);

switch (item.getItemId())

{

case (MENU_UPDATE):

{

refreshEarthquakes();

return true;

}

}

return false;

}

11. 现在,添加一些用户交互。当用户从地震列表中选择一项时,打开一个对话框,显示更多的地震细节。

11.1 创建新的quake_details.xml layout资源,作为用户点击项目时显示的对话框的布局。

<?xml version=”1.0” encoding=”utf-8”?>

<LinearLayout

xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”vertical”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”

android:padding=”10sp”>

<TextView

android:id=”@+id/quakeDetailsTextView”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”

android:textSize=”14sp”

/>

</LinearLayout>

11.2 然后,修改onCreate方法,为ListView添加一个onItemClickListener,当一个地震项目选择时显示一个对话框。

static final private int QUAKE_DIALOG = 1;

Quake selectedQuake;

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

earthquakeListView =

(ListView)this.findViewById(R.id.earthquakeListView);

earthquakeListView.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView _av, View _v, int _index, long arg3) {

selectedQuake = earthquakes.get(_index);

showDialog(QUAKE_DIALOG);

}

});

int layoutID = android.R.layout.simple_list_item_1;

aa = new ArrayAdapter<Quake>(this, layoutID , earthquakes);

earthquakeListView.setAdapter(aa);

refreshEarthquakes();

}

11.3 现在,重写onCreateDialog和onPrepareDialog方法来创建对话框和填入地震细节。

@Override

public Dialog onCreateDialog(int id) {

switch(id) {

case (QUAKE_DIALOG) :

LayoutInflater li = LayoutInflater.from(this);

View quakeDetailsView = li.inflate(R.layout.quake_details, null);

AlertDialog.Builder quakeDialog = new AlertDialog.Builder(this);

quakeDialog.setTitle(“Quake Time”);

quakeDialog.setView(quakeDetailsView);

return quakeDialog.create();

}

return null;

}

@Override

public void onPrepareDialog(int id, Dialog dialog) {

switch(id) {

case (QUAKE_DIALOG) :

SimpleDateFormat sdf;

sdf = new SimpleDateFormat(“dd/MM/yyyy HH:mm:ss”);

String dateString = sdf.format(selectedQuake.getDate());

String quakeText = “Mangitude “ + selectedQuake.getMagnitude() +

“\n” + selectedQuake.getDetails() + “\n” + selectedQuake.getLink();

AlertDialog quakeDialog = (AlertDialog)dialog;

quakeDialog.setTitle(dateString);

TextView tv =

(TextView)quakeDialog.findViewById(R.id.quakeDetailsTextView);

tv.setText(quakeText);

break;

}

}

11.4 最后一步,为对话框制作超链接指向USGS。调整对话框的XML layout资源定义,包含一个autolink特性。

<?xml version=”1.0” encoding=”utf-8”?>

<LinearLayout

xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”vertical”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”

android:padding=”10sp”>

<TextView

android:id=”@+id/quakeDetailsTextView”

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”

android:textSize=”14sp”

android:autoLink=”all”

/>

</LinearLayout>

再次运行你的Activity。当你点击某个地震项目时,一个对话框会显示出来,并使列表部分模糊,如图5-7所示。

图5-7

Sample Code:

http://files.cnblogs.com/xirihanlin/DL090804@cc-Earthquake.zip

Sample图示:

创建一个地震Viewer相关推荐

  1. 创建一个Android Cardboard 360 Video Viewer

    建立 在开始构建视频查看器应用程序之前,您将需要通过Git将Cardboard Android SDK克隆到计算机上. 您可以在本系列的上一篇文章中找到有关此操作的说明. 对于我们的示例,使用最低AP ...

  2. 创建一个Windows Service应用程序

    创建一个Windows Service应用程序 下载本文代码 见资源 正是由于.NET Framework的出现,才使你能够构建出在系统重新启动时自动运行的.无人参与的(unattended)应用程序 ...

  3. RTX5 | 软件定时器02 - 创建一个软件定时器(连续运行)

    文章目录 一.前言 二.实验目的 三.API 3.1.osTimerNew 3.2.osTimerStart 四.代码 4.1.main.h 4.2.main.c 五.Event Recorder调试 ...

  4. 【云计算 | OpenStack】从零开始使用libvirt创建一个kvm虚机

    环境: os镜像:CentOS-7-x86_64-Minimal-2009.iso qemu-kvm:qemu-kvm.x86_64 10:1.5.3-175.el7_9.6 Libvirt:libv ...

  5. 在cesium上面创建一个显示隐藏功能和移动的功能,附加相机飞入

    ** 目的功能:创建一个显示隐藏功能和移动的功能,附加相机飞入 ** 先写一个.json文件,我在这里起名scene.json {"title": "新建场景" ...

  6. 使用HTML5的Canvas和raycasting创建一个伪3D游戏(part1)

    使用HTML5的Canvas和raycasting创建一个伪3D游戏(part1) 刚来这找到一篇好文,自己翻译了下:(原文:http://dev.opera.com/articles/view/cr ...

  7. Foxit MobilePDF SDK_如何快速创建一个功能丰富的PDF 阅读器

    一直以来,我都比较关注福昕的PDF SDK套件,这几天稍微有时间看了下最新发布的4.0版本,然后呢,然后呢,我就被深深的震惊到了,为甚么? 因为这个版本可以很轻松很容易的创建一个功能超级丰富的PDF阅 ...

  8. linux创建一个交换分区,如何创建linux交换分区

    匿名用户 1级 2017-03-26 回答 1.mkswap 把一个分区格式化成为swap交换区: [root@localhost]# mkswap /dev/sda6 注:创建此分区为swap 交换 ...

  9. 创建一个Scalar-valued Function函数来实现LastIndexOf

    昨天有帮助网友解决的个字符串截取的问题,<截取字符串中最后一个中文词语(MS SQL)>http://www.cnblogs.com/insus/p/7883606.html 虽然实现了, ...

  10. 如何创建一个基础jQuery插件

    如何创建一个基础插件 How to Create a Basic Plugin 有时你想使一块功能性的代码在你代码的任何地方有效.比如,也许你想调用jQuery对象的一个方法,对该对象进行一系列的操作 ...

最新文章

  1. 知乎高赞:iOS 为什么感觉比 Android 流畅?
  2. python中requests库的用途-python中requests库session对象的妙用详解
  3. SVN服务器和客户端的基本使用详细图解
  4. Linux的Nginx四:功能|模块
  5. Django错误解决: CSRF verification failed. Request abor
  6. java并发-多线程方面的思考
  7. 用PPT制作 电子相册,进行抽奖准备.
  8. CentOS7.0离线安装RHadoop
  9. 【技术帖】真正解决反恐精英csOL:StartService 0X204 为防御非法程序driver
  10. 2006中秋节短信,最新中秋节祝福短信
  11. spark-streaming 编程(四)自定义输出foreachRDD
  12. 一篇文章教你搞懂日志采集利器 Filebeat
  13. Linux虚拟机下FTP服务器的搭建(详细)
  14. 湖北省安陆市发展怎么样
  15. 【Flink】参数不生效
  16. 支付宝钱包系统架构内部剖析
  17. ipconfig/all详解
  18. 根据城市查找编号,根据编号查找城市
  19. 高德置地广场UTOPA HUB来了!弄潮玩家们的杭州新聚场!
  20. 03.Git 分支管理【详细图文】

热门文章

  1. 四张照片合成一张怎么弄_教你5种照片创意手工,简单好看实用
  2. 计算机专业基础 -- Spring系列框架相关基础知识
  3. 重置 Mac 上的 NVRAM 或 PRAM
  4. 浏览器控件JxBrowser V6.14大版本发布 | 注入CSS
  5. 01 Django简介
  6. Asia Hong Kong Regional Contest 2016
  7. Android 学习笔记之Volley(七)实现Json数据加载和解析...
  8. selinux为enforcing模式时,运行anonymous上传之后无法删除
  9. pytorh——Fully-connected
  10. 第四季-专题20-SPI驱动程序设计