Android中加入名片扫描功能实例代码

要想实现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”文件里添加以下权限:

<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>标签里添加注册信息:

<activity android:name="cn.maketion.uploadSdk.MkxActivityCamera"/>

三、相机页面

cn.maketion.uploadSdk.MkxActivityCamera是sdk提供的基于Activity相机页面,用于拍摄名片并自动提交云端识别。可以使用

如下方式调用:

Intent intent = new Intent(this, MkxActivityCamera.class);
startActivity(intent); 

四、SDK函数

cn.maketion.uploadSdk.MkxServer类是个单例。首先获取此类的实例,然后通过实例调用此类的所有功能函数

1、获取MkxServer类实例

public static MkxServer getServer(Application app)

通过此函数可以获取MkxServer的实例。

2、验证功能

public void auth(String key, String secure, String uid, MkxBackInit back)
public boolean isAuth()
public void clearAuth() 

验证功能包括三个函数:auth()提交验证;isAuth()判断验证状态;clearAuth()清除验证状态。

参数key:由脉可寻名片识别服务申请获得;

参数secure:由脉可寻名片识别服务申请获得;

参数back:回调接口

3、获取名片信息

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、监听上传事件

public void setUploadListener(MkxBackUpload back)

通过设置回调函数,监听上传事件。

参数back:回调接口, 见第五章第4节

5、上传名片图片

public void uploadImage(String uuid)

当监听上传事件时发生上传失败,可以通过此函数进行重新上传。

参数uuid:要上传的名片的uuid

6、设置Sdcard图片缓存路径

public void setSdcardPath(String sdcardPath)

设置Sdcard路径后,拍摄名片所生成的图片,会保持在此路径下。

参数sdcardPath:Sdcard上的缓存路径,例如:setSdcardPath("ImageCache");

拍摄的名片将保存到“\sdcard\ImageCache\”路径下。

7、获取名片原图

public void getCardImage(String uuid, MkxBackPicture back)

通过名片的uuid获取名片原图。此函数会先检查图片缓存路径是否存在对应的原图(名片uuid即为名片在缓存路径下的名字),若存在则直接返回此文件名,若不存在则先下载再返回。

参数uuid: 要获取原图的名片的uuid

参数back: 回调接口,

五、回调接口

1、错误信息

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、验证回调接口

public interface MkxBackAuth extends MkxErrorCode {
void onBack(int code, String errInfo);
} 

参数code:网络调用状态,如果code值为CODE_SUCCESS表示验证通过;

参数errInfo:当网络调用失败时,返回错误参考信息。

3、获取名片信息回调接口

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、上传监听回调接口

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、获取名片原图回调接口

public interface MkxBackPicture {
void onBack(File picture);
}

参数picture:名片原图文件,若picture为null表示获取原图失败;

软件包的分层结构

接下来看,我自己做了一个小demo,测试扫描名片功能

项目内容

在Mainfest.xml文件中加入权限和Activity

<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实例,并判断是否已经验证

@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方法

/**
* 验证账户
*/
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();
}
}
});
}
}

拍照功能

/**
* 拍照操作
*/
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

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。

结果不尽人意~~

(0)

相关推荐

  • Android项目中引用本地aar文件的方法

    随着项目越来越多,代码的复用就变得异常重要,这时候就要进行模块化编程,就是把一些通用的组件或者类库做成单独的模块,其他项目直接进行引用就好.针对Android开发最常见的就是Android Library,在Gradle出现之前引用Android Library的方式也很繁琐,但是有了Gradle一切变得非常简单方便. aar 何为aar?大家都知道jar文件把,如果你有一个Android Library项目,可以很容易的导出jar文件,然后在其他项目中很方便的引用,aar和jar类似,区别就是

  • Android扫描本地音乐文件开发案例分享

    一.前言 本来觉得so easy,真是没想到,还搞了老半天,搞的我大汗淋漓,要拍桌子摔键盘了. 本想实现的功能是: 通过网易云音乐/百度音乐/QQ音乐/酷狗音乐中一个API,通过关键词/歌手/歌词来搜索相关歌曲信息,然后在线播放.下载到本地,不过目前来看,使用API还是有一点问题.通过浏览器访问,问题不大,例如下图: 但是想通过手机访问的时候,问题就出现了,同样的参数,结果很不一样,而且基本搜不到自己想要的,后来换做通过自己的服务器去访问,还是搜不到,后来查了一下资料,暂时也没解决.于是,目前就

  • Android编程获取sdcard音乐文件的方法

    本文实例讲述了Android编程获取sdcard音乐文件的方法.分享给大家供大家参考,具体如下: 复制代码 代码如下: Cursor  query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder); Uri:指明要查询的数据库名称加上表的名称,从MediaStore中我们可以找到相应信息的参数,具体请参考开发文档. Projection: 指定查询数据库表中的哪几列,

  • Android编程简单实现雷达扫描效果

    本文实例讲述了Android编程简单实现雷达扫描效果.分享给大家供大家参考,具体如下: 在eoe看到有一篇关于雷达扫描的文章,然后看了下,很简单,但是觉得还有很多可以优化的地方,下面贴出来 package com.example.wave; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; im

  • Android中扫描多媒体文件操作详解

    这篇文章从系统源代码分析,讲述如何将程序创建的多媒体文件加入系统的媒体库,如何从媒体库删除,以及大多数程序开发者经常遇到的无法添加到媒体库的问题等.本人将通过对源代码的分析,一一解释这些问题. Android中的多媒体文件扫描机制 Android提供了一个很棒的程序来处理将多媒体文件加入的媒体库中.这个程序就是MediaProvider,现在我们简单看以下这个程序.首先看一下它的Receiver 复制代码 代码如下: <receiver android:name="MediaScanner

  • android获取音乐文件的内置专辑图片实现思路及代码

    代码和注释如下: 复制代码 代码如下: private Cursor getCursor(String filePath) { String path = null; Cursor c = getContentResolver().query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); // System.out.printl

  • 基于Android扫描sd卡与系统文件的介绍

    如果你做过多媒体应用,一定会苦恼过,怎样获取sd卡中的多媒体文件.android还是很强大的,如果你知道怎么调用android的api,万事就ok了. 当手机或模拟器开机时,会调用android的MediaScanner,扫描sd卡和内存里的文件.以下是log信息. 复制代码 代码如下: 12-13 15:39:11.062: VERBOSE/MediaPlayerService(67): Create new media retriever from pid 349<BR> 12-13 15

  • android暂停或停止其他音乐播放器的播放实现代码

    代码如下: 复制代码 代码如下: public static final String PLAYSTATE_CHANGED = "com.android.music.playstatechanged";    public static final String META_CHANGED = "com.android.music.metachanged";    public static final String QUEUE_CHANGED = "com

  • Android应用中实现选择本地文件与目录的实例分享

    文件选择器 今天给大家分享下文件选择器的作用 , 具体就是获取用户在在SD卡选中的文件/文件夹路径 ,类似于C#中OpenFileDialog控件(对C#的一站式开发还是念念不忘).功能实现起来比较简单,主要是帮助大家节省开发时间. 网上流传较广的一个成品如下 <[Android实例] 文件选择器>, 本文也是根据上面的成品修改而成,使其更易理解,效率更高. 除此之外,主要特色有: 1.我们监听了用户按下Back键的事件,使其返回上一层目录: 2.针对不同的文件类型(文件vs文件夹 , 目标文

  • Android中通过MediaStore获取音乐文件信息方法

    Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,并且提供了一套数据库表格,通过Content Provider的方式提供给用户.当手机开机或者有SD卡插拔等事件发生时,系统将会自动扫描SD卡和手机内存上的媒体文件,如audio,video,图片等,将相应的信息放到定义好的数据库表格中.在这个程序中,我们不需要关心如何去扫描手机中的文件,只要了解如何查询和使用这些信息就可以了. MediaStore中定义了一系列的数据表格,通过Conten

随机推荐