使用Zxing及豆瓣API
Posted on 2012/12/06归档于 ANDROID最近在做团队图书管理的一个Android端。因为需要通过手机扫描来输入图书信息(人工一条一条地输入,作为技术人员太受不了了),需要使用ZXing的API扫描图书ISBN,及使用豆瓣API来获取图书信息。
由于时间关系,这里没有使用ZXing的jar包,而是下载并安装了它的开源项目——条码扫描器,然后调用里面的Activity扫描再获取结果。
首先到市场下载Barcode Scaner(或搜索条码扫描器),下载安装。
下面先贴上Activity的布局代码,因为是demo版,而且在内部使用,就没去好好做布局设计,只是把需要的控件都写上。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
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上获得最新代码。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189/*
* @(#)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
*
*
* 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
;
@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的过程比较简单,
12Intent intent =
new
Intent(
"com.google.zxing.client.android.SCAN"
);
this
.startActivityForResult(intent, HOME_ACTIVITY);
然后再在onActivityResult方法中对返回的结果进行处理就好了。
然后从豆瓣API中获得的是xml格式的内容,这里我就使用了android自带的pull解析器。我需要获得的图书信息相对较少,Book的JavaBean如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798/*
* @(#)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
*
*
* 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 +
"]"
;
}
}
然后解析器的代码如下:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394/*
* @(#)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
*
*
* 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资源,如下:
123456789101112131415<
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
>
转载于:https://www.cnblogs.com/lexus/archive/2013/01/27/2878482.html