`
貌似掉线
  • 浏览: 256561 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

使用Zxing及豆瓣API

阅读更多
本文原创,转载请注明原文地址:http://maosidiaoxian.iteye.com/blog/1743296或我在sinaapp上的博客:http://msdxblog.sinaapp.com/?p=716。

最近在做团队图书管理的一个Android端。因为需要通过手机扫描来输入图书信息(人工一条一条地输入,作为技术人员太受不了了),需要使用ZXing的API扫描图书ISBN,及使用豆瓣API来获取图书信息。

由于时间关系,这里没有使用ZXing的jar包,而是下载并安装了它的开源项目——条码扫描器,然后调用里面的Activity扫描再获取结果。
首先到市场下载Barcode Scaner(或搜索条码扫描器),下载安装。
下面先贴上Activity的布局代码,因为是demo版,而且在内部使用,就没去好好做布局设计,只是把需要的控件都写上。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/home_scan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_scan" />

    <TextView
        android:id="@+id/home_result_scan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/home_book_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/home_upload_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_upload" />

    <TextView
        android:id="@+id/home_result_upload"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="false" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/home_borrow_book"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/borrow_book" />

        <Spinner
            android:id="@+id/home_users"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right" />
    </LinearLayout>

    <Button
        android:id="@+id/home_return_book"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/return_book" />

    <Button
        android:id="@+id/home_user_manager"
        android:layout_width="wrap_content"
        android:text="@string/manager_user"
        android:layout_height="wrap_content" />

</LinearLayout>


然后在我们的项目中,写一个Activity来调用Zxing的扫描功能,并通过它返回的结果访问互联网获取信息。

下面是该Activity的代码。这里对于控件及事件的绑定,我使用了自己封装的一个工具(Androidkit)来简化这些代码,所以你们会看到许多类似@AndroidView的注解,这个工具可以在http://code.google.com/p/cfuture-androidkit/获取,或从https://github.com/msdx/androidkit上获得最新代码。
/*
 * @(#)HomeActivity.java		       Project:bookscan
 * Date:2012-12-3
 *
 * Copyright (c) 2011 CFuture09, Institute of Software, 
 * Guangdong Ocean University, Zhanjiang, GuangDong, China.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sinaapp.msdxblog.bookscan.activity;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.TextView;

import com.sinaapp.msdxblog.androidkit.thread.HandlerFactory;
import com.sinaapp.msdxblog.androidkit.ui.ResBindUtil;
import com.sinaapp.msdxblog.androidkit.ui.UIBindUtil;
import com.sinaapp.msdxblog.androidkit.ui.annotation.AndroidRes;
import com.sinaapp.msdxblog.androidkit.ui.annotation.AndroidRes.ResType;
import com.sinaapp.msdxblog.androidkit.ui.annotation.AndroidView;
import com.sinaapp.msdxblog.androidkit.ui.annotation.OnClick;
import com.sinaapp.msdxblog.bookscan.R;
import com.sinaapp.msdxblog.bookscan.bean.Book;
import com.sinaapp.msdxblog.bookscan.util.DB;
import com.sinaapp.msdxblog.bookscan.util.XMLSax;

/**
 * @author Geek_Soledad (66704238@51uc.com)
 */
public class HomeActivity extends Activity {
	private static final int HOME_ACTIVITY = 1990;
	private static final String DOUBAN_API = "http://api.douban.com/book/subject/isbn/";

	@AndroidView(id = R.id.home_result_scan)
	private TextView mTextScan;
	@AndroidView(id = R.id.home_book_info)
	private TextView mTextBook;
	@AndroidView(id = R.id.home_result_upload)
	private TextView mTextUpload;
	@AndroidView(id = R.id.home_users)
	private Spinner mSpinnerUser;

	@AndroidRes(id = R.string.result_scan, type = ResType.STRING)
	private String mStringScan;
	@AndroidRes(id = R.string.result_getting, type = ResType.STRING)
	private String mStringGetting;
	@AndroidRes(id = R.string.book_info, type = ResType.STRING)
	private String mStringBookInfo;

	private Handler mGettingBook;
	private Book book;
	private DB mDb;
	private SimpleCursorAdapter mAdapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		UIBindUtil.bind(this, R.layout.activity_home);
		ResBindUtil.bindAllRes(this);
		init();
	}

	/**
	 * 初始化参数。
	 */
	private final void init() {
		mGettingBook = HandlerFactory.getNewHandlerInOtherThread("book");
		mDb = new DB(this);
		Cursor users = mDb.getAllUser();
		startManagingCursor(users);
		mAdapter = new SimpleCursorAdapter(this,
				android.R.layout.simple_spinner_item, users,
				new String[] { "username" }, new int[] { android.R.id.text1 });
		mAdapter
		.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		mSpinnerUser.setAdapter(mAdapter);

	}

	@OnClick(viewId = { R.id.home_scan, R.id.home_upload_result,
			R.id.home_borrow_book, R.id.home_return_book,
			R.id.home_user_manager })
	public void onButtonClick(View v) {
		switch (v.getId()) {
		case R.id.home_scan:
			Intent intent = new Intent("com.google.zxing.client.android.SCAN");
			this.startActivityForResult(intent, HOME_ACTIVITY);
			break;
		case R.id.home_upload_result:
			break;
		case R.id.home_borrow_book:
			break;
		case R.id.home_return_book:
			break;
		case R.id.home_user_manager:
			startActivity(new Intent(this, UserManagerActivity.class));
			break;
		default:
			break;
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode != HOME_ACTIVITY) {
			super.onActivityResult(requestCode, resultCode, data);
			return;
		}
		if (data == null) {
			return;
		}
		final String isbn = data.getStringExtra("SCAN_RESULT");
		mTextScan.setText(String.format(mStringScan, isbn));
		if (isbn != null) {
			mTextBook.setText(mStringGetting);
			mGettingBook.post(new Runnable() {

				@Override
				public void run() {
					DefaultHttpClient client = new DefaultHttpClient();
					HttpGet request = new HttpGet(DOUBAN_API + isbn);
					try {
						HttpResponse response = client.execute(request);
						book = XMLSax.sax(response.getEntity().getContent());
						String summary = book.getSummary();
						summary = summary.substring(0,
								summary.length() < 60 ? summary.length() : 60)
								.concat("...");
						String string = String.format(mStringBookInfo,
								book.getName(), book.getAuthor(),
								book.getPublisher(), book.getIsbn13(), summary);
						updateBookInfoView(string);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}

			});
		}
	}

	/**
	 * 更新图书信息
	 * 
	 * @param string
	 */
	private void updateBookInfoView(final String string) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				mTextBook.setText(string);
			}
		});
	}

	@Override
	protected void onResume() {
		super.onResume();
		mAdapter.notifyDataSetChanged();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mDb.close();
	}
}

里面的功能及流程大致如下:
调用Zxinig的扫描条码的Activity,然后返回该扫描结果,显示扫描结果,然后调用豆瓣的API获取图书信息。接下来是要从我们的服务器上获得该图书的信息(如是否登记,有没有人借走等),但因为服务端还没搭建好,这一部分功能就没去实现。
上面代码中,调用Zxing的过程比较简单,
			Intent intent = new Intent("com.google.zxing.client.android.SCAN");
			this.startActivityForResult(intent, HOME_ACTIVITY);

然后再在onActivityResult方法中对返回的结果进行处理就好了。
然后从豆瓣API中获得的是xml格式的内容,这里我就使用了android自带的pull解析器。我需要获得的图书信息相对较少,Book的JavaBean如下:
/*
 * @(#)BookInfo.java		       Project:bookscan
 * Date:2012-12-3
 *
 * Copyright (c) 2011 CFuture09, Institute of Software, 
 * Guangdong Ocean University, Zhanjiang, GuangDong, China.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sinaapp.msdxblog.bookscan.bean;

/**
 * @author Geek_Soledad (66704238@51uc.com)
 */
public class Book {

	private String isbn10;// 10位的ISBN
	private String isbn13;// 13位的ISBN
	private String name; // 书名
	private String author;// 作者名
	private String summary;// 简介
	private String publisher; // 出版社
	private String image; // 封面图片地址

	public String getIsbn10() {
		return isbn10;
	}

	public void setIsbn10(String isbn10) {
		this.isbn10 = isbn10;
	}

	public String getIsbn13() {
		return isbn13;
	}

	public void setIsbn13(String isbn13) {
		this.isbn13 = isbn13;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}

	public String getPublisher() {
		return publisher;
	}

	public void setPublisher(String publisher) {
		this.publisher = publisher;
	}

	public String getImage() {
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

	@Override
	public String toString() {
		return "Book [isbn10=" + isbn10 + ", isbn13=" + isbn13 + ", name="
				+ name + ", author=" + author + ", summary=" + summary
				+ ", publisher=" + publisher + ", image=" + image + "]";
	}
}


然后解析器的代码如下:
/*
 * @(#)XMLSax.java		       Project:bookscan
 * Date:2012-12-3
 *
 * Copyright (c) 2011 CFuture09, Institute of Software, 
 * Guangdong Ocean University, Zhanjiang, GuangDong, China.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sinaapp.msdxblog.bookscan.util;

import java.io.IOException;
import java.io.InputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import com.sinaapp.msdxblog.bookscan.bean.Book;

import android.util.Log;
import android.util.Xml;

/**
 * @author Geek_Soledad (66704238@51uc.com)
 */
public class XMLSax {

	public static Book sax(InputStream is) {
		Book book = null;
		XmlPullParser parser = Xml.newPullParser();
		try {
			parser.setInput(is, "UTF-8");
			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				switch (eventType) {
				case XmlPullParser.START_TAG:
					Log.d("test", parser.getName());
					if (parser.getName().equals("entry")) {
						book = new Book();
					} else if (parser.getName().equals("link")) {
						if (parser.getAttributeValue(null, "rel").equals("image")) {
							book.setImage(parser.getAttributeValue(null, "href"));
						}
						eventType = parser.next();
					}
					else if (parser.getName().equals("attribute")) {
						String attribute = parser.getAttributeValue(0);
						eventType = parser.next();
						if (attribute.equals("title")) {
							book.setName(parser.getText());
						} else if (attribute.equals("author")) {
							book.setAuthor(parser.getText());
						} else if (attribute.equals("isbn10")) {
							book.setIsbn10(parser.getText());
						} else if (attribute.equals("isbn13")) {
							book.setIsbn13(parser.getText());
						} else if ( attribute.equals("publisher")) {
							book.setPublisher(parser.getText());
						} 
					} else if (parser.getName().equals("summary")) {
						eventType = parser.next();
						book.setSummary(parser.getText());
					} else if (parser.getName().equals("title")) {
						if (book.getName() == null) {
							eventType = parser.next();
							book.setName(parser.getText());
						}
					}
					break;
				case XmlPullParser.END_TAG:
					break;
				}
				eventType = parser.next();
			}

		} catch (XmlPullParserException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return book;
	}
}

然后是引用到的String资源,如下:
<resources>

    <string name="app_name">图书扫描</string>
    <string name="bookmark_picker_name">Bookmarks</string>
    <string name="button_scan">图书扫描</string>
    <string name="button_upload">上传结果</string>
    <string name="result_scan">扫描结果为:%s</string>
    <string name="result_getting">正在向豆瓣请求数据</string>
    <string name="book_info">图书信息:\n\t书名:%1$s\n\t作者:%2$s\n\t出版社:%3$s\n\tISBN:%4$s\n\t简介:%5$s </string>
    <string name="borrow_book">借书</string>
    <string name="return_book">还书</string>
    <string name="manager_user">管理用户</string>
    <string name="add">添加</string>
    <string name="delete">删除</string>
</resources>

最后的结果是这样子的:
  • 大小: 90.3 KB
1
0
分享到:
评论
3 楼 linxu8520 2013-09-06  
貌似掉线 写道
linxu8520 写道
求import com.sinaapp.msdxblog.bookscan.util.DB;代码~~   谢谢~~

项目在这里:
http://code.google.com/p/android-applications-codes/source/browse/#svn%2Ftrunk%2Fbookmanager4cf


十分感谢~~
2 楼 貌似掉线 2013-09-05  
linxu8520 写道
求import com.sinaapp.msdxblog.bookscan.util.DB;代码~~   谢谢~~

项目在这里:
http://code.google.com/p/android-applications-codes/source/browse/#svn%2Ftrunk%2Fbookmanager4cf
1 楼 linxu8520 2013-09-05  
求import com.sinaapp.msdxblog.bookscan.util.DB;代码~~   谢谢~~

相关推荐

    android利用ZXing Jsoup 和豆瓣API做出的图书搜索.zip源码资源下载

    android利用ZXing Jsoup 和豆瓣API做出的图书搜索.zip源码资源下载android利用ZXing Jsoup 和豆瓣API做出的图书搜索.zip源码资源下载

    android应用源码利用ZXing Jsoup 和豆瓣API做出的图书搜索源码

    android应用源码利用ZXing Jsoup 和豆瓣API做出的图书搜索源码.,android安卓实例应用源代码,仅供学习及设计参考。

    Android数据扫描条形码源码-基于zxing和XUtils使用豆瓣API

    Android数据扫描条形码源码-基于zxing和XUtils使用豆瓣API 不多说啦,直接看代码吧,因为使用了第三方的框架,用起来很简单。 XUtils只使用了Http和Bitmap工具,用的不多不想依赖第三方框架的同学自己改吧。

    android利用ZXing-Jsoup-和豆瓣API做出的图书搜索.zip

    android利用ZXing-Jsoup-和豆瓣API做出的图书搜索.zip

    android利用ZXing Jsoup 和豆瓣API做出的图书搜索.zip

    Android 应用开发源码 参考与学习使用

    android利用ZXing Jsoup 和豆瓣API做出的图书搜索-IT计算机-毕业设计.zip

    Android应用源码开发Demo,主要用于毕业设计学习。

    源码 android利用ZXing Jsoup 和豆瓣API做出的图书搜索.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...

    书籍条形码扫描源码

    使用了zxing和豆瓣的api,参考了网友的代码。

    扫扫图书源码.zip

    扫扫图书源码主要的技术就是Zxing开源库的使用,简单的网络通信,数据解析及UI更新的要点。扫描书籍的条形码以后。返回ISBN值之后,然后再去豆瓣图书API:http://developers.douban.com/wiki/?title=book_v2上获取...

    Android应用源码扫描书籍条形码获取书籍信息图书扫扫

    本项目是一个图书条形码扫描的应用项目源码,主要的技术就是Zxing开源库的使用,简单的网络通信,数据解析及UI更新的要点。扫描书籍的条形码以后。返回ISBN值之后,然后再去豆瓣图书API:...

    扫扫图书

    扫扫图书源码主要的技术就是Zxing开源库的使用,简单的网络通信,数据解析及UI更新的要点。扫描书籍的条形码以后。返回ISBN值之后,然后再去豆瓣图书API:,然后解析,更新到UI上MainActivity.java是主界面的...

    java开源包8

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包1

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包11

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包2

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包3

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包6

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包5

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包10

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包4

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

Global site tag (gtag.js) - Google Analytics