要想实现android手机通过扫描名片,得到名片信息,可以使用脉可寻提供的第三方sdk,即maketion scancard sdk,脉可寻云名片识别服务。他们的官方网站为http://www.maketion.com/。
一、概述
maketion scancardsdk(以下简称sdk)是提供给第三方合作伙伴接入脉可寻云名片识别服务,合作伙伴需要先申请key和secure才可以使用。
sdk不能独立运行,使用时需要嵌入到android的project中。
sdk支持android2.1版本及以上版本的project。
脉可寻识别服务的流程为:认证->打开sdk相机页面->拍摄名片->确认上传成功->获取数据。
二、安装过程
1.将“scancardsdk.jar”加到工程的“lib/”目录下
2.将“libappmain.so”加到工程的“lib/armeabi/”目录下
3.在工程的“androidmanifest.xml”文件里添加以下权限:
1
2
3
4
5
6
7
|
<uses-feature android:name= "android.hardware.camera" />
<uses-feature android:name= "android.hardware.camera.autofocus" />
<uses-permission android:name= "android.permission.camera" />
<uses-permission android:name= "android.permission.internet" />
<uses-permission android:name= "android.permission.access_fine_location" />
<uses-permission android:name= "android.permission.access_network_state" />
<uses-permission android:name= "android.permission.write_external_storage" />
|
4.继续在“androidmanifest.xml”的<application>标签里添加注册信息:
1
|
<activity android:name= "cn.maketion.uploadsdk.mkxactivitycamera" />
|
三、相机页面
cn.maketion.uploadsdk.mkxactivitycamera是sdk提供的基于activity相机页面,用于拍摄名片并自动提交云端识别。可以使用
如下方式调用:
1
2
|
intent intent = new intent( this , mkxactivitycamera. class );
startactivity(intent);
|
四、sdk函数
cn.maketion.uploadsdk.mkxserver类是个单例。首先获取此类的实例,然后通过实例调用此类的所有功能函数
1、获取mkxserver类实例
1
|
public static mkxserver getserver(application app)
|
通过此函数可以获取mkxserver的实例。
2、验证功能
1
2
3
|
public void auth(string key, string secure, string uid, mkxbackinit back)
public boolean isauth()
public void clearauth()
|
验证功能包括三个函数:auth()提交验证;isauth()判断验证状态;clearauth()清除验证状态。
参数key:由脉可寻名片识别服务申请获得;
参数secure:由脉可寻名片识别服务申请获得;
参数back:回调接口
3、获取名片信息
1
2
|
public void getdatawithuuid(string[] uuids, final mkxbackcards back)
public void getdatawithtime( long time, final mkxbackcards back)
|
获取名片信息有两种方式:通过名片的关键字uuid获取名片信息;获取一个时间点之后的所有名片信息。
参数uuids:字符串数组,每个字符串为一个名片的uuid;
参数time:时间点, 1970年1月1日开始经过的“秒”(数若此参数为0表示获取所有名片信息,不包含已删除的名片和无法识别的名片);
参数back:回调接口
4、监听上传事件
1
|
public void setuploadlistener(mkxbackupload back)
|
通过设置回调函数,监听上传事件。
参数back:回调接口, 见第五章第4节
5、上传名片图片
1
|
public void uploadimage(string uuid)
|
当监听上传事件时发生上传失败,可以通过此函数进行重新上传。
参数uuid:要上传的名片的uuid
6、设置sdcard图片缓存路径
1
|
public void setsdcardpath(string sdcardpath)
|
设置sdcard路径后,拍摄名片所生成的图片,会保持在此路径下。
参数sdcardpath:sdcard上的缓存路径,例如:setsdcardpath("imagecache");
拍摄的名片将保存到“\sdcard\imagecache\”路径下。
7、获取名片原图
1
|
public void getcardimage(string uuid, mkxbackpicture back)
|
通过名片的uuid获取名片原图。此函数会先检查图片缓存路径是否存在对应的原图(名片uuid即为名片在缓存路径下的名字),若存在则直接返回此文件名,若不存在则先下载再返回。
参数uuid: 要获取原图的名片的uuid
参数back: 回调接口,
五、回调接口
1、错误信息
1
2
3
4
5
6
7
8
9
10
|
public interface mkxerrorcode {
int code_success = 0 ;
int code_fail_result = 1 ; // 结果错误
int code_fail_decode = 2 ; // json解析时出错
int code_fail_null = 3 ; // 网络错误,包括500或502错误
int code_fail_timeout = 4 ; // 连接超时
int code_fail_network = 5 ; // 网络错误,无网络或网络不可用
int code_fail_repeat = 6 ; // 接口重复调用,未等到接口返回就进行二次调用
int code_fail_unknow = 9 ; // 未知错误
}
|
所有网络访问函数调用时都会返回状态码code,当code的值为code_success时表示接口调用成功,否则表示接口调用失败。
2、验证回调接口
1
2
3
|
public interface mkxbackauth extends mkxerrorcode {
void onback( int code, string errinfo);
}
|
参数code:网络调用状态,如果code值为code_success表示验证通过;
参数errinfo:当网络调用失败时,返回错误参考信息。
3、获取名片信息回调接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class mkxcard {
public string carduuid ; // 名片uuid
public string name ; // 姓名
public string duty ; // 头衔
public string mobile1 ; // 手机1
public string mobile2 ; // 手机2
public string email ; // 邮箱
public string tel1 ; // 电话1
public string tel2 ; // 电话2
public string fax ; // 传真
public string cname ; // 公司名
public string address ; // 地址
public string website ; // 网址
public string logo ; // 头像
public long createtime ; // 创建时间
public long updatetime ; // 更新时间
public string fields ; // 已完成字段,"100"为全部完成
public int audit ; // 是否无法识别,大于1就是无法识别
public int flag ; // 标识,0为有效,1为已删除
}
public interface mkxbackcards extends mkxerrorcode {
void onback( int code, string errinfo, mkxcard[] cards);
}
|
参数code:网络调用状态;
参数errinfo:当网络调用失败时,返回错误参考信息;
参数cards:返回的名片信息数组。
4、上传监听回调接口
1
2
3
4
5
6
|
public interface mkxbackupload extends mkxerrorcode {
int status_start = 0 ;
int status_sucess = 1 ;
int status_error = 2 ;
void onback( int code, string errinfo, string uuid, int status);
}
|
参数code:网络调用状态;
参数errinfo:当网络调用失败时,返回错误参考信息;
参数uuid:当前上传名片uuid;
参数status:status_start表示开始上传,status_sucess表示上传成功,status_error表示上传失败。
5、获取名片原图回调接口
1
2
3
|
public interface mkxbackpicture {
void onback(file picture);
}
|
参数picture:名片原图文件,若picture为null表示获取原图失败;
软件包的分层结构
接下来看,我自己做了一个小demo,测试扫描名片功能
项目内容
在mainfest.xml文件中加入权限和activity
1
2
3
4
5
6
7
8
9
10
|
<uses-feature android:name= "android.hardware.camera" />
<uses-feature android:name= "android.hardware.camera.autofocus" />
<uses-permission android:name= "android.permission.camera" />
<uses-permission android:name= "android.permission.internet" />
<uses-permission android:name= "android.permission.access_fine_location" />
<uses-permission android:name= "android.permission.access_network_state" />
<uses-permission android:name= "android.permission.write_external_storage" />
<activity android:name= "cn.maketion.uploadsdk.mkxactivitycamera" />
<activity android:name= "com.example.maketiontest.carddetailactivity" />
<activity android:name= "com.example.maketiontest.maketionactivity" />
|
maketionactivity中主要是两个方法takepic()方法和authenticateaccount()方法。
首先在oncreate方法中,得到mkxserver实例,并判断是否已经验证
1
2
3
4
5
6
7
8
9
10
11
12
|
@override
protected void oncreate(bundle arg0) {
// todo auto-generated method stub
super .oncreate(arg0);
server = mkxserver.getserver(getapplication());
isinit = server.isauth();
if (isinit) {
takepic();
} else {
authenticateaccount();
}
}
|
如果已经验证就进行拍照,如果还没有验证,就验证
authenticateaccount方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/**
* 验证账户
*/
private void authenticateaccount() {
if (!isinit) {
server.auth(key, secret, puid, new mkxbackauth() {
@override
public void onback( int code, string errinfo) {
if (code == mkxerrorcode.code_success) {
isinit = server.isauth();
if (isinit) {
log.i(tag, "验证成功!" );
takepic();
} else {
log.i(tag, "验证失败!" );
finish();
}
} else {
log.i(tag, errinfo);
finish();
}
}
});
}
}
|
拍照功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
/**
* 拍照操作
*/
private void takepic() {
if (isinit) {
server.setuploadlistener( new mkxbackupload() {
@override
public void onback( int code, string errinfo, string uuid,
int status) {
log.i(tag, uuid);
muuid = uuid;
switch (status) {
case status_error: // 上传出错
if (uploadtimes <= 5 ) { // 由于重新上传与拍照上传都是调用统一上传函数,因此需要限制重传次数,避免上传图片时产生无限递归
uploadtimes++;
server.uploadimage(uuid); // 重新上传
} else { // 重新上传的次数达到上限时,不再上传,保存不能上传图片的uuid
uploadtimes = 0 ;
uploadfails.add(uuid);
log.i(tag, "上传失败,等待网络通畅时再重新上传" );
}
break ;
case status_start: // 开始上传
break ;
case status_sucess: // 上传成功
server.getdatawithuuid( new string[] { uuid },
new mkxbackcards() {
@override
public void onback( int code, string cards,
mkxcard[] arg2) {
// todo auto-generated method stub
if (code == mkxerrorcode.code_success) {
if (isinit) { //上传成功则进入名片页面
intent intent = new intent(
maketionactivity. this ,
carddetailactivity. class );
intent.putextra( "uuid" , muuid);
startactivity(intent);
} else {
log.i(tag, "还未验证账户" );
}
}
}
});
log.i(tag, "上传成功" );
break ;
}
}
});
intent intent = new intent( this , mkxactivitycamera. class );
startactivity(intent);
} else {
log.i(tag, "还未验证账户,请验证账户再获取数据" );
finish();
}
}
|
carddetailactivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
protected void oncreate(bundle savedinstancestate) {
// todo auto-generated method stub
super .oncreate(savedinstancestate);
log.i(tag, "carddetailactivity------>oncreate" );
setcontentview(r.layout.card_detail_activity);
server = mkxserver.getserver(getapplication());
if (getintent() != null
&& !textutils.isempty(getintent().getstringextra( "uuid" ))) {
string uuid = getintent().getstringextra( "uuid" ).tostring();
// 获取单张名片信息
server.getdatawithuuid( new string[] { uuid }, new mkxbackcards() {
@override
public void onback( int code, string info, mkxcard[] cards) {
if (code == mkxerrorcode.code_success) {
log.i(tag, " " + cards.length);
if (cards.length != 0 ) {
setview(cards);
}
}
}
});
} else {
log.i(tag, "没有获取uuid" );
}
}
|
让我比较疑惑的事情是为什么在获得单张名片信息的时候,回调方法onback中,参数是mkxcard[] cards
为什么是个对象数组呢= =。看不到sdk的源码,没办法~
运行之后,并不是每张照片都能得到信息,总的来说,还是不怎么好用,建议以后用二维码会更好,或者用nfc。
结果不尽人意~~