2008年10月29日星期三

Android解析KML

KML服务有两种,一种是纯文本的XML,一种是将一个纯文本的XML文件和其他资源(如图标)进行zip压缩后形成的KMZ,本质是zip。使用Android解析KML服务需要根据情况首先判断是否需要解压缩,然后再解析XML文本。

Android Java中包含了zip压缩解压缩工具库,可以从“java.util.zip”包中进行调用。我们看一下一个KMZ如何被解压缩:

URL url = new URL(strUrl);
HttpURLConnection uc = (HttpURLConnection) url.openConnection();

InputStream isKxml = null;

ZipInputStream zipIs = new ZipInputStream(uc.getInputStream());
ZipEntry zipEntry = null;
while ((zipEntry = zipIs.getNextEntry()) != null)
{
String zipEntryName = zipEntry.getName();
if (zipEntryName.endsWith("kml"))
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] b = new byte[512];
int readedByteSize = 0;
while ((readedByteSize = zipIs.read(b)) > 0)
{
os.write(b, 0, readedByteSize);
}
os.flush();
os.close();

isKxml = new ByteArrayInputStream(os.toByteArray());
}
else if (zipEntryName.endsWith("png"))
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] b = new byte[512];
int readedByteSize = 0;
while ((readedByteSize = zipIs.read(b)) > 0)
{
os.write(b, 0, readedByteSize);
}
os.flush();
os.close();

InputStream isBitmap = new ByteArrayInputStream(os
.toByteArray());
Bitmap bitmap = BitmapFactory.decodeStream(isBitmap);
kml.addBitmap(zipEntryName, bitmap);
isBitmap.close();
}
}
zipIs.close();

Reader reader = new InputStreamReader(isKxml);
parseKxml(kml, reader);//解析KML文本的方法
isKxml.close();
reader.close();

好了,解压缩完成后,重点就在解析KML文本上了。鉴于移动终端的KML内容不应该很大,因此在这里使用了XmlDocument方法解析,下面看一下方法:

private static void parseKxml(Kml kml, Reader reader) throws Exception
{
KXmlParser kXmlParser = new KXmlParser();
kXmlParser.setInput(reader);
Document doc = new Document();
doc.parse(kXmlParser);

if (doc == null) return;

Element eRoot = doc.getRootElement();
……(处理XML Element)
}

2 条评论:

Unknown 说...

请问一下 zipIs.getNextEntry() 碰到一个中文名的XML文件是不是执行不了啊。。 我在android 上用getNextEntry() 碰到压缩包里面文件名是中文的就不行了。。 不知道为什么呢。。。

牛魔王 说...

没试过中文,可能吧