大家好,最近在DeviceOne平台上做了一个汉王云名片识别的功能组件。下面把我开发过程给大家做一个分享,希望可以帮助到大家。

下面我把我的思路给大家讲解一下。

1.找到我要集成的sdk,也就是汉王云名片的sdk下载(android和ios)和文档下载。

2.阅读sdk的官方demo

3.在deviceone上面创建组件

4.编写组件的属性、事件、方法。

5.下载组件的项目

6.编码

7.上传zip包

8.编写示例进行调试

9.完成。

下面我就按照上面的顺序来依次讲解。

1.找到我要集成的sdk,也就是汉王云名片的sdk下载(android和ios)和文档下载。

打开http://developer.hanvon.com/,开发者中心,注册了一个账号,然后选择我要开发的sdk页面进行示例demo下载http://developer.hanvon.com/api/toAPIinfo.do?id=2。

2.阅读sdk的官方demo并申请相关的android的key和ios的key

下面我分两个平台给大家讲解下代码:

Android:

我们看下上面的图片,这个是官方给的例子,一共就一个类 ,这样我们直接看代码。

public class MainActivity extends Activity {

private Button button1;

private Button button2;

private ImageView iv_image;

private TextView testView;

private ProgressDialog pd;

private DiscernHandler discernHandler;

String picPath = null;

String result = null;

private HWCloudManager hwCloudManagerBcard;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title bar

setContentView(R.layout.activity_main);

/**

* your_android_key  是您在开发者中心申请的android_key 并 申请了云身份证识别服务

* 开发者中心:http://developer.hanvon.com/

*/

hwCloudManagerBcard = new HWCloudManager(this, "your_android_key");

discernHandler = new DiscernHandler();

button1 = (Button) findViewById(R.id.button1);

button2 = (Button) findViewById(R.id.button2);

iv_image = (ImageView) findViewById(R.id.iv_image);

testView = (TextView) findViewById(R.id.result);

button1.setOnClickListener(listener);

button2.setOnClickListener(listener);

}

OnClickListener listener = new OnClickListener() {

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.button1:

// 激活系统图库,选择一张图片

Intent intent = new Intent();

intent.setAction(Intent.ACTION_PICK);

intent.setType("image/*");

startActivityForResult(intent, 0);

break;

case R.id.button2:

//识别

testView.setText("");

ConnectionDetector connectionDetector = new ConnectionDetector(getApplication());

if (connectionDetector.isConnectingTOInternet()) {

if (null != picPath) {

pd = ProgressDialog.show(MainActivity.this, "", "正在识别请稍后......");

DiscernThread discernThread = new DiscernThread();

new Thread(discernThread).start();

} else {

Toast.makeText(getApplication(), "请选择图片后再试", Toast.LENGTH_LONG).show();

}

} else {

Toast.makeText(getApplication(), "网络连接失败,请检查网络后重试!", Toast.LENGTH_LONG).show();

}

break;

}

}

};

public class DiscernThread implements Runnable{

@Override

public void run() {

try {

/**

* 调用汉王云名片识别方法

*/

result = hwCloudManagerBcard.cardLanguage("chns", picPath);

// result = hwCloudManagerBcard.cardLanguage4Https("chns", picPath);

} catch (Exception e) {

// TODO: handle exception

}

Bundle mBundle = new Bundle();

mBundle.putString("responce", result);

Message msg = new Message();

msg.setData(mBundle);

discernHandler.sendMessage(msg);

}

}

public class DiscernHandler extends Handler {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

pd.dismiss();

Bundle bundle = msg.getData();

String responce = bundle.getString("responce");

testView.setText(responce);

}

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (data != null) {

Uri uri = data.getData();

String[] proj = { MediaStore.Images.Media.DATA };

Cursor cursor = getContentResolver().query(uri, proj, null, null, null);

int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

cursor.moveToFirst();

picPath = cursor.getString(column_index);

System.out.println(picPath);

final BitmapFactory.Options options = new BitmapFactory.Options();

options.inJustDecodeBounds = true;

BitmapFactory.decodeFile(picPath, options);

options.inSampleSize = BitmapUtil.calculateInSampleSize(options, 1280, 720);

options.inJustDecodeBounds = false;

Bitmap bitmap = BitmapFactory.decodeFile(picPath, options);

iv_image.setImageBitmap(bitmap);

}

super.onActivityResult(requestCode, resultCode, data);

}

}

上面就是官方给的代码,我们可以看到,整个过程就是:首先后去一个图片,也就是名片的照片,然后就是通过云端去处理这个图片,然后返回一个json值,就是我们要的结果了。那么我们直接看部分代码解析。

// 激活系统图库,选择一张图片

Intent intent = new Intent();

intent.setAction(Intent.ACTION_PICK);

intent.setType("image/*");

startActivityForResult(intent, 0);

选择一个图片,并获取返回的地址。

//识别

testView.setText("");

ConnectionDetector connectionDetector = new ConnectionDetector(getApplication());

if (connectionDetector.isConnectingTOInternet()) {

if (null != picPath) {

pd = ProgressDialog.show(MainActivity.this, "", "正在识别请稍后......");

DiscernThread discernThread = new DiscernThread();

new Thread(discernThread).start();

} else {

Toast.makeText(getApplication(), "请选择图片后再试", Toast.LENGTH_LONG).show();

}

} else {

Toast.makeText(getApplication(), "网络连接失败,请检查网络后重试!", Toast.LENGTH_LONG).show();

}

进行识别。

从上面两个代码我们可以看出,整个sdk的核心部分就是这两块,这样,我们就了解了整个sdk的核心东西了。

IOS:

下面我们看下ios的项目目录

上面就是目录结构,非常简单。废话不多说,我们直接看代码。

#import"ViewController.h"

#import"HWCloudsdk.h"

@interfaceViewController()

@end

@implementationViewController

- (void)viewDidLoad {

[superviewDidLoad];

HWCloudsdk*sdk = [[HWCloudsdkalloc]init];

UIImage*cardImg = [UIImageimageNamed:@"cardimage.jpg"];

//apiKey需要您到developer.hanvon.com自行申请

NSString*apiKey =@"your - ios - key";

[sdkcardLanguage:@"auto"cardImage:cardImgapiKey:apiKeysuccessBlock:^(idresponseObject) {

NSLog(@"%@",responseObject);

}failureBlock:^(NSError*error) {

NSLog(@"%@",error);

}];

//    NSString *str = [sdk cardLanguage:@"chns" cardImage:cardImg apiKey:apiKey];

//    NSLog(@"返回的结果是: %@",str);

// Do any additional setup after loading the view, typically from a nib.

}

- (void)didReceiveMemoryWarning {

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

以上就是代码,非常的简单,就几句话。我们来分析一下。

HWCloudsdk*sdk = [[HWCloudsdkalloc]init];

UIImage*cardImg = [UIImageimageNamed:@"cardimage.jpg"];

//apiKey需要您到developer.hanvon.com自行申请

NSString*apiKey =@"your - ios - key";

[sdkcardLanguage:@"auto"cardImage:cardImgapiKey:apiKeysuccessBlock:^(idresponseObject) {

NSLog(@"%@",responseObject);

}failureBlock:^(NSError*error) {

NSLog(@"%@",error);

}];

上面这段代码就是整个核心,我们看一下,就是获取一个图片,然后通过图片去云端解析,更加简洁。

这样我们就解读好了sdk的demo,也知道如何来使用了。

3.在deviceone上面创建组件

我觉得这个可以省略的,那我直接用文字来描述一下吧。

创建账号-开发者中心-组件开发-创建组件-填写信息-保存。

搞定。

4.编写组件的属性、事件、方法。

通过我们上面的阅读sdk的demo,我们可以非常清晰的知道了我们需要如何来调用,那么我就定义一个方法就可以了

在这里面我定义的方法为getInfo方法,我给这个方法的一个参数为imgUrl,也就是需要一个图片的路径。

下面我直接上图,给大家看看我的配置。

这个就是我配置好的,供大家参考。

5.下载组件的项目

通过步骤4的编写,我们现在就可以去下载组件开发项目了。

6.编码

这个章节大家可能是最关心的一节,那我细一点讲解。我分两个平台讲解:

Android:

我们先看下载好的项目并且导入到我的ADT中(这个地方大家可以使用自己的eclipse开发),看下项目图

上面就是我导入之后的项目目录,下面进行一下目录的讲解:

doext文件下下面的所有文件都是官方生成好的,也是我们这次开发组件编写代码的文件夹。

dotest.module这个文件夹是用于我们进行原生测试组件的属性、事件、方法的。这个后续会使用到,请继续往下看。

我们接下来打开doext/implement/组件名_Model.java文件。(因为我们是一个sm组件,所以有这样一个文件。)

我们下面来看看这个文件的代码:

publicclassM1294_hwymp_ModelextendsDoSingletonModuleimplementsM1294_hwymp_IMethod{

publicM1294_hwymp_Model()throwsException {

super();

}

/**

*同步方法,JS脚本调用该组件对象方法时会被调用,可以根据_methodName调用相应的接口实现方法;

* @_methodName方法名称

* @_dictParas参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine当前Page JS上下文环境对象

* @_invokeResult用于返回方法结果对象

*/

@Override

publicbooleaninvokeSyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, DoInvokeResult _invokeResult)

throwsException {

//...do something

returnsuper.invokeSyncMethod(_methodName, _dictParas, _scriptEngine, _invokeResult);

}

/**

*异步方法(通常都处理些耗时操作,避免UI线程阻塞),JS脚本调用该组件对象方法时会被调用,

*可以根据_methodName调用相应的接口实现方法;

* @_methodName方法名称

* @_dictParas参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine当前page JS上下文环境

* @_callbackFuncName回调函数名

* #如何执行异步方法回调?可以通过如下方法:

* _scriptEngine.callback(_callbackFuncName, _invokeResult);

*参数解释:@_callbackFuncName回调函数名,@_invokeResult传递回调函数参数对象;

*获取DoInvokeResult对象方式new DoInvokeResult(this.getUniqueKey());

*/

@Override

publicbooleaninvokeAsyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, String _callbackFuncName)throwsException {

//...do something

returnsuper.invokeAsyncMethod(_methodName, _dictParas, _scriptEngine, _callbackFuncName);

}

/**

*获取名片信息;

* @_dictParas参数(K,V),可以通过此对象提供相关方法来获取参数值(Key:为参数名称);

* @_scriptEngine当前Page JS上下文环境对象

* @_callbackFuncName回调函数名

*/

@Override

publicvoidgetInfo(JSONObject _dictParas, DoIScriptEngine _scriptEngine,String _callbackFuncName) {

}

}

整个这个代码是我们定义好组件之后,官方生成好的,经过阅读,我们看到这个代码的中文解析已经很清晰了,那我在这里在解析一下,

里面有两个方法,一个是同步方法,一个是异步方法,这个是根据我们定义的组件的方法性质来说的,但是一般建议使用异步方法,这样不会出现

屏幕卡顿的现象,我用的是异步方法。所以下面的编程,我就在异步方法里面编写就可以了。

还有一个就是getInfo这个方法,看到这个方法很熟悉吧,因为是我们在组件里面定义过的,就是这个方法,看来我们要定义自己的逻辑就要在这个方法

里面写了,这样我们就清晰的知道了我们要写组件代码的去处了。

下一步就是我们开始写了。

/**

*异步方法(通常都处理些耗时操作,避免UI线程阻塞),JS脚本调用该组件对象方法时会被调用,

*可以根据_methodName调用相应的接口实现方法;

* @_methodName方法名称

* @_dictParas参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine当前page JS上下文环境

* @_callbackFuncName回调函数名

* #如何执行异步方法回调?可以通过如下方法:

* _scriptEngine.callback(_callbackFuncName, _invokeResult);

*参数解释:@_callbackFuncName回调函数名,@_invokeResult传递回调函数参数对象;

*获取DoInvokeResult对象方式new DoInvokeResult(this.getUniqueKey());

*/

@Override

publicbooleaninvokeAsyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, String _callbackFuncName)throwsException {

if("getInfo".equals(_methodName))

{

getInfo(_dictParas, _scriptEngine, _callbackFuncName);

}

returnsuper.invokeAsyncMethod(_methodName, _dictParas, _scriptEngine, _callbackFuncName);

}

看上面的代码,我把我写的这段话标注为红色了,大家可以看的清楚一下,我写这段话的目的就是要判断一下我传入的方法进行相应的调用,

也就是说我们通常写组件的时候,这个地方可能会有好几个方法,所以这个地方会有好几个判断的。这样讲大家就清楚了。

下面,我们就把之前的demo的代码直接拷贝到当前的项目中,然后倒入jar包(这个不讲了,如果不会可以百度倒入jar包)。直接代码

publicclassM1294_hwymp_ModelextendsDoSingletonModuleimplementsM1294_hwymp_IMethod{

privateButton button1;

privateButton button2;

privateImageView iv_image;

privateTextView testView;

privateProgressDialog pd;

privateDiscernHandler discernHandler;

String picPath =null;

String result =null;

privateHWCloudManager hwCloudManagerBcard;

publicM1294_hwymp_Model()throwsException {

super();

}

/**

*同步方法,JS脚本调用该组件对象方法时会被调用,可以根据_methodName调用相应的接口实现方法;

* @_methodName方法名称

* @_dictParas参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine当前Page JS上下文环境对象

* @_invokeResult用于返回方法结果对象

*/

@Override

publicbooleaninvokeSyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, DoInvokeResult _invokeResult)

throwsException {

//...do something

returnsuper.invokeSyncMethod(_methodName, _dictParas, _scriptEngine, _invokeResult);

}

/**

*异步方法(通常都处理些耗时操作,避免UI线程阻塞),JS脚本调用该组件对象方法时会被调用,

*可以根据_methodName调用相应的接口实现方法;

* @_methodName方法名称

* @_dictParas参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine当前page JS上下文环境

* @_callbackFuncName回调函数名

* #如何执行异步方法回调?可以通过如下方法:

* _scriptEngine.callback(_callbackFuncName, _invokeResult);

*参数解释:@_callbackFuncName回调函数名,@_invokeResult传递回调函数参数对象;

*获取DoInvokeResult对象方式new DoInvokeResult(this.getUniqueKey());

*/

@Override

publicbooleaninvokeAsyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, String _callbackFuncName)throwsException {

//...do something

returnsuper.invokeAsyncMethod(_methodName, _dictParas, _scriptEngine, _callbackFuncName);

}

/**

*获取名片信息;

* @_dictParas参数(K,V),可以通过此对象提供相关方法来获取参数值(Key:为参数名称);

* @_scriptEngine当前Page JS上下文环境对象

* @_callbackFuncName回调函数名

*/

@Override

publicvoidgetInfo(JSONObject _dictParas, DoIScriptEngine _scriptEngine,String _callbackFuncName) {

hwCloudManagerBcard =newHWCloudManager(this,"your_android_key");

discernHandler =newDiscernHandler();

button1 = (Button) findViewById(R.id.button1);

button2 = (Button) findViewById(R.id.button2);

iv_image = (ImageView) findViewById(R.id.iv_image);

testView = (TextView) findViewById(R.id.result);

button1.setOnClickListener(listener);

button2.setOnClickListener(listener);

}

OnClickListener listener =newOnClickListener() {

@Override

publicvoidonClick(View view) {

switch(view.getId()) {

caseR.id.button1:

//激活系统图库,选择一张图片

Intent intent =newIntent();

intent.setAction(Intent.ACTION_PICK);

intent.setType("image/*");

startActivityForResult(intent,0);

break;

caseR.id.button2:

//识别

testView.setText("");

ConnectionDetector connectionDetector =newConnectionDetector(getApplication());

if(connectionDetector.isConnectingTOInternet()) {

if(null!= picPath) {

pd = ProgressDialog.show(MainActivity.this,"","正在识别请稍后......");

DiscernThread discernThread =newDiscernThread();

newThread(discernThread).start();

}else{

Toast.makeText(getApplication(),"请选择图片后再试", Toast.LENGTH_LONG).show();

}

}else{

Toast.makeText(getApplication(),"网络连接失败,请检查网络后重试!", Toast.LENGTH_LONG).show();

}

break;

}

}

};

publicclassDiscernThreadimplementsRunnable{

@Override

publicvoidrun() {

try{

/**

*调用汉王云名片识别方法

*/

result = hwCloudManagerBcard.cardLanguage("chns", picPath);

// result = hwCloudManagerBcard.cardLanguage4Https("chns", picPath);

}catch(Exception e) {

// TODO: handle exception

}

Bundle mBundle =newBundle();

mBundle.putString("responce", result);

Message msg =newMessage();

msg.setData(mBundle);

discernHandler.sendMessage(msg);

}

}

publicclassDiscernHandlerextendsHandler {

@Override

publicvoidhandleMessage(Message msg) {

super.handleMessage(msg);

pd.dismiss();

Bundle bundle = msg.getData();

String responce = bundle.getString("responce");

testView.setText(responce);

}

}

@Override

protectedvoidonActivityResult(intrequestCode,intresultCode, Intent data) {

if(data !=null) {

Uri uri = data.getData();

//閫氳繃uri鑾峰彇鍥剧墖璺緞

String[] proj = { MediaStore.Images.Media.DATA };

Cursor cursor = getContentResolver().query(uri, proj,null,null,null);

intcolumn_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

cursor.moveToFirst();

picPath = cursor.getString(column_index);

System.out.println(picPath);

finalBitmapFactory.Options options =newBitmapFactory.Options();

options.inJustDecodeBounds =true;

BitmapFactory.decodeFile(picPath, options);

options.inSampleSize = BitmapUtil.calculateInSampleSize(options,1280,720);

options.inJustDecodeBounds =false;

Bitmap bitmap = BitmapFactory.decodeFile(picPath, options);

iv_image.setImageBitmap(bitmap);

}

super.onActivityResult(requestCode, resultCode, data);

}

}

上面的代码,标记为紫色的是我第一次要去掉的代码,原因:因为我是直接传入的照片的地址,所以跟照片有关系的我都不需要了。

publicclassM1294_hwymp_ModelextendsDoSingletonModuleimplementsM1294_hwymp_IMethod{

privateDiscernHandler discernHandler;

String picPath =null;

String result =null;

privateHWCloudManager hwCloudManagerBcard;

publicM1294_hwymp_Model()throwsException {

super();

}

/**

*同步方法,JS脚本调用该组件对象方法时会被调用,可以根据_methodName调用相应的接口实现方法;

* @_methodName方法名称

* @_dictParas参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine当前Page JS上下文环境对象

* @_invokeResult用于返回方法结果对象

*/

@Override

publicbooleaninvokeSyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, DoInvokeResult _invokeResult)

throwsException {

//...do something

returnsuper.invokeSyncMethod(_methodName, _dictParas, _scriptEngine, _invokeResult);

}

/**

*异步方法(通常都处理些耗时操作,避免UI线程阻塞),JS脚本调用该组件对象方法时会被调用,

*可以根据_methodName调用相应的接口实现方法;

* @_methodName方法名称

* @_dictParas参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine当前page JS上下文环境

* @_callbackFuncName回调函数名

* #如何执行异步方法回调?可以通过如下方法:

* _scriptEngine.callback(_callbackFuncName, _invokeResult);

*参数解释:@_callbackFuncName回调函数名,@_invokeResult传递回调函数参数对象;

*获取DoInvokeResult对象方式new DoInvokeResult(this.getUniqueKey());

*/

@Override

publicbooleaninvokeAsyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, String _callbackFuncName)throwsException {

if("getInfo".equals(_methodName))

{

getInfo(_dictParas, _scriptEngine, _callbackFuncName);

}

returnsuper.invokeAsyncMethod(_methodName, _dictParas, _scriptEngine, _callbackFuncName);

}

/**

*获取名片信息;

* @_dictParas参数(K,V),可以通过此对象提供相关方法来获取参数值(Key:为参数名称);

* @_scriptEngine当前Page JS上下文环境对象

* @_callbackFuncName回调函数名

*/

@Override

publicvoidgetInfo(JSONObject _dictParas, DoIScriptEngine _scriptEngine,String _callbackFuncName) {

hwCloudManagerBcard =newHWCloudManager(this,"your_android_key");

discernHandler =newDiscernHandler();

ConnectionDetector connectionDetector =newConnectionDetector(getApplication());

if(connectionDetector.isConnectingTOInternet()) {

if(null!= picPath) {

DiscernThread discernThread =newDiscernThread();

newThread(discernThread).start();

}else{

Toast.makeText(getApplication(),"请选择图片后再试", Toast.LENGTH_LONG).show();

}

}else{

Toast.makeText(getApplication(),"网络连接失败,请检查网络后重试!", Toast.LENGTH_LONG).show();

}

}

}

};

publicclassDiscernThreadimplementsRunnable{

@Override

publicvoidrun() {

try{

/**

*调用汉王云名片识别方法

*/

result = hwCloudManagerBcard.cardLanguage("chns", picPath);

// result = hwCloudManagerBcard.cardLanguage4Https("chns", picPath);

}catch(Exception e) {

// TODO: handle exception

}

Bundle mBundle =newBundle();

mBundle.putString("responce", result);

Message msg =newMessage();

msg.setData(mBundle);

discernHandler.sendMessage(msg);

}

}

publicclassDiscernHandlerextendsHandler {

@Override

publicvoidhandleMessage(Message msg) {

super.handleMessage(msg);

pd.dismiss();

Bundle bundle = msg.getData();

String responce = bundle.getString("responce");

testView.setText(responce);

}

}

}

上面这段代码基本是我去掉后的代码,看起来好像是没什么问题,那我们在看看,在精简一下。

public class M1294_hwymp_Model extends DoSingletonModule implements M1294_hwymp_IMethod{

String picPath = null;

String result = null;

private HWCloudManager hwCloudManagerBcard;

public M1294_hwymp_Model() throws Exception {

super();

}

/**

* 同步方法,JS脚本调用该组件对象方法时会被调用,可以根据_methodName调用相应的接口实现方法;

* @_methodName 方法名称

* @_dictParas 参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine 当前Page JS上下文环境对象

* @_invokeResult 用于返回方法结果对象

*/

@Override

public boolean invokeSyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, DoInvokeResult _invokeResult)

throws Exception {

//...do something

return super.invokeSyncMethod(_methodName, _dictParas, _scriptEngine, _invokeResult);

}

/**

* 异步方法(通常都处理些耗时操作,避免UI线程阻塞),JS脚本调用该组件对象方法时会被调用,

* 可以根据_methodName调用相应的接口实现方法;

* @_methodName 方法名称

* @_dictParas 参数(K,V),获取参数值使用API提供DoJsonHelper类;

* @_scriptEngine 当前page JS上下文环境

* @_callbackFuncName 回调函数名

* #如何执行异步方法回调?可以通过如下方法:

* _scriptEngine.callback(_callbackFuncName, _invokeResult);

* 参数解释:@_callbackFuncName回调函数名,@_invokeResult传递回调函数参数对象;

* 获取DoInvokeResult对象方式new DoInvokeResult(this.getUniqueKey());

*/

@Override

public boolean invokeAsyncMethod(String _methodName, JSONObject _dictParas,

DoIScriptEngine _scriptEngine, String _callbackFuncName)throws Exception {

if("getInfo".equals(_methodName))

{

getInfo(_dictParas, _scriptEngine, _callbackFuncName);

}

return super.invokeAsyncMethod(_methodName, _dictParas, _scriptEngine, _callbackFuncName);

}

/**

* 获取名片信息;

* @_dictParas 参数(K,V),可以通过此对象提供相关方法来获取参数值(Key:为参数名称);

* @_scriptEngine 当前Page JS上下文环境对象

* @_callbackFuncName 回调函数名

*/

@Override

public void getInfo(JSONObject _dictParas, DoIScriptEngine _scriptEngine,String _callbackFuncName) {

ApplicationInfo info = null;

try {

info = DoServiceContainer.getPageViewFactory().getAppContext().getPackageManager().getApplicationInfo(DoServiceContainer.getPageViewFactory().getAppContext().getPackageName(), PackageManager.GET_META_DATA);

//添加判断

String androidKey = info.metaData.getString("hwymp_android");

hwCloudManagerBcard = new HWCloudManager(DoServiceContainer.getPageViewFactory().getAppContext(), androidKey);

picPath = DoJsonHelper.getString(_dictParas, "imgUrl", "");

if(DoIOHelper.existFile(DoIOHelper.getLocalFileFullPath(_scriptEngine.getCurrentApp(), picPath)))

{

picPath = DoIOHelper.getLocalFileFullPath(_scriptEngine.getCurrentApp(), picPath);

}

} catch (Exception e) {

e.printStackTrace();

}

ConnectionDetector connectionDetector = new ConnectionDetector(DoServiceContainer.getPageViewFactory().getAppContext());

if (connectionDetector.isConnectingTOInternet()) {

if (null != picPath) {

result = hwCloudManagerBcard.cardLanguage("chns", picPath);

DoInvokeResult invokeResult = new DoInvokeResult(getUniqueKey());

invokeResult.setResultText(result);

_scriptEngine.callback(_callbackFuncName, invokeResult);

} else {

new Exception("请传入图片后再试");

}

} else {

new Exception("网络连接失败,请检查网络后重试!");

}

}

}

上面这段代码是我精简之后的,看起来是不是简介了很多,我现在讲解一下如何精简的,

publicclassDiscernThreadimplementsRunnable{

@Override

publicvoidrun() {

try{

/**

*调用汉王云名片识别方法

*/

result = hwCloudManagerBcard.cardLanguage("chns", picPath);

// result = hwCloudManagerBcard.cardLanguage4Https("chns", picPath);

}catch(Exception e) {

// TODO: handle exception

}

Bundle mBundle =newBundle();

mBundle.putString("responce", result);

Message msg =newMessage();

msg.setData(mBundle);

discernHandler.sendMessage(msg);

}

}

publicclassDiscernHandlerextendsHandler {

@Override

publicvoidhandleMessage(Message msg) {

super.handleMessage(msg);

pd.dismiss();

Bundle bundle = msg.getData();

String responce = bundle.getString("responce");

testView.setText(responce);

}

}

这两段代码完全是没有用的,因为我们是异步方法,已经在一个线程里面了,不需要再去new一个线程,还要像主线程发消息,好复杂,而且容易出错

没有用,去掉就可以了。然后就有上面的简介代码了。

info = DoServiceContainer.getPageViewFactory().getAppContext().getPackageManager().getApplicationInfo(DoServiceContainer.getPageViewFactory().getAppContext().getPackageName(), PackageManager.GET_META_DATA);

//添加判断

String androidKey = info.metaData.getString("hwymp_android");

这段代码就是我在manifest里面定义了一个,这样方便我在发布到商店的时候,可以让其他开发者去使用自己的key

这样,我们的组件算是写好了,下面的工作就是我们要去dotest里面来测试一下我们的组件是否正确运行了,go

我们首先找到dotest/module/activity/webviewsampletestactivity.java文件,直接看代码吧。

public class WebViewSampleTestActivty extends DoTestActivity{

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

@Override

protected void initModuleModel() throws Exception {

this.model = new M1294_hwymp_Model();

}

@Override

protected void initUIView() throws Exception {

// Do_WebView_View view = new Do_WebView_View(this);

//        ((DoUIModule)this.model).setCurrentUIModuleView(view);

//        ((DoUIModule)this.model).setCurrentPage(currentPage);

//        view.loadView((DoUIModule)this.model);

//        LinearLayout uiview = (LinearLayout)findViewById(R.id.uiview);

//        uiview.addView(view);

}

@Override

public void doTestProperties(View view) {

DoService.setPropertyValue(this.model, "url", "https://www.baidu.com");

}

@Override

protected void doTestSyncMethod() {

Map _paras_back = new HashMap();

DoService.syncMethod(this.model, "back", _paras_back);

}

@Override

protected void doTestAsyncMethod() {

Map  _paras_loadString = new HashMap();

_paras_loadString.put("imgUrl", "/storage/emulated/0/tencent/MicroMsg/WeiXin/mmexport1473648247058.jpg.do");

DoService.asyncMethod(this.model, "getInfo", _paras_loadString, new DoService.EventCallBack() {

@Override

public void eventCallBack(String _data) {//回调函数

DoServiceContainer.getLogEngine().writeDebug("异步方法回调:" + _data);

}

});

}

@Override

protected void onEvent() {

DoService.subscribeEvent(this.model, "loaded", new DoService.EventCallBack() {

@Override

public void eventCallBack(String _data) {

DoServiceContainer.getLogEngine().writeDebug("事件回调:" + _data);

}

});

}

@Override

public void doTestFireEvent(View view) {

DoInvokeResult invokeResult = new DoInvokeResult(this.model.getUniqueKey());

this.model.getEventCenter().fireEvent("_messageName", invokeResult);

}

}

看下上面标红的部分,因为我这个组件是sm的组件,所以跟UI相关的我需要,所以注释掉,然后找到方法的地方,将我东西初始化并调用方法。

这样直接在android上面运行这个项目就可以了。

至此,我的android项目编写完成。

IOS:

看下项目的目录

点击doExtLib右键,添加新文件,导入之后的图片

然后我们点击“组件_sm.m”文件看下代码。

@implementationM1294_hwymp_SM

#pragma mark -方法

#pragma mark -同步异步方法的实现

//同步

//异步

- (void)getInfo:(NSArray*)parms

{

//异步耗时操作,但是不需要启动线程,框架会自动加载一个后台线程处理这个函数

NSDictionary*_dictParas = [parmsobjectAtIndex:0];

//参数字典_dictParas

id _scritEngine = [parmsobjectAtIndex:1];

//自己的代码实现

NSString*_callbackName = [parmsobjectAtIndex:2];

//回调函数名_callbackName

doInvokeResult*_invokeResult = [[doInvokeResultalloc]init];

//_invokeResult设置返回值

[_scritEngineCallback:_callbackName :_invokeResult];

}

@end

代码非常简单,我们直观的看到了我们创建好的组件,我们来看下里面的中文解释也是非常的清晰,下面我们直接贴代码。

导入.a文件的步骤省略(百度)

@implementationM1294_hwymp_SM

#pragma mark -方法

#pragma mark -同步异步方法的实现

//同步

//异步

- (void)getInfo:(NSArray*)parms

{

//异步耗时操作,但是不需要启动线程,框架会自动加载一个后台线程处理这个函数

NSDictionary*_dictParas = [parmsobjectAtIndex:0];

//参数字典_dictParas

id _scritEngine = [parmsobjectAtIndex:1];

//自己的代码实现

NSString*_callbackName = [parmsobjectAtIndex:2];

//回调函数名_callbackName

doInvokeResult*_invokeResult = [[doInvokeResultalloc]init];

//_invokeResult设置返回值

HWCloudsdk *sdk = [[HWCloudsdk alloc]init];

UIImage *cardImg = [UIImage imageNamed:@"cardimage.jpg"];

//apiKey需要您到developer.hanvon.com自行申请

NSString*apiKey =@"your - ios - key";

[sdk cardLanguage:@"auto"cardImage:cardImg apiKey:apiKey successBlock:^(idresponseObject) {

NSLog(@"%@",responseObject);

} failureBlock:^(NSError *error) {

NSLog(@"%@",error);

}];

[_scritEngineCallback:_callbackName :_invokeResult];

}

@end

红色为示例demo下面的代码,直接贴过来,我们在看下。

看过之后,好像离我们要的组件编码已经很接近了。修改代码如下。

@implementationM1294_hwymp_SM

#pragma mark -方法

#pragma mark -同步异步方法的实现

//同步

//异步

- (void)getInfo:(NSArray*)parms

{

//异步耗时操作,但是不需要启动线程,框架会自动加载一个后台线程处理这个函数

NSDictionary*_dictParas = [parmsobjectAtIndex:0];

//参数字典_dictParas

id _scritEngine = [parmsobjectAtIndex:1];

NSString*_callbackName = [parmsobjectAtIndex:2];

//获取图片地址

NSString*url = [doJsonHelperGetOneText:_dictParas :@"imgUrl":@""];

UIImage*cardImg = [UIImageimageWithContentsOfFile: [doIOHelperGetLocalFileFullPath:[_scritEngineCurrentApp] :url]];

//初始化HWCloud

HWCloudsdk*sdk = [[HWCloudsdkalloc]init];

//apiKey需要您到developer.hanvon.com自行申请

NSString*apiKey = [[doServiceContainerInstance].ModuleExtManageGetThirdAppKey:@"hwymp.plist":@"hwymp_ios"];

[sdkcardLanguage:@"chns"cardImage:cardImgapiKey:apiKeysuccessBlock:^(idresponseObject) {

doInvokeResult*_invokeResult = [[doInvokeResultalloc]init];

[_invokeResultSetResultText:responseObject];

[_scritEngineCallback:_callbackName :_invokeResult];

}failureBlock:^(NSError*error) {

NSLog(@"%@",error);

}];

}

上面蓝色部分为我修改过的代码。我在项目中自己定义了一个plist文件,用于去key值,方便以后提交到上面,开发者可以填写自己的key

这样我编码就完成了,接下来测试。我们打开do_test文件夹下面的viewcontroller。直接看源码。

#import"ViewController.h"

#import"doPage.h"

#import"doService.h"

#import"doModuleFactory.h"

#import"M1294_hwymp_SM.h"

@interfaceViewController()

{

@private

NSString*Type;

doModule* model;

}

@end

@implementationCallBackEvnet

-(void)eventCallBack:(NSString*)_data

{

NSLog(@"异步方法回调数据:%@",_data);

}

@end

@implementationViewController

- (void)viewDidLoad {

[superviewDidLoad];

[selfInitInstance];

[selfConfigUI];

// Do any additional setup after loading the view, typically from a nib.

}

- (void) InitInstance

{

NSString*testPath = [[NSBundlemainBundle]pathForResource:@"do_Test"ofType:@"json"];

NSData*data = [NSDatadataWithContentsOfFile:testPath];

NSMutableDictionary*_testDics = [NSJSONSerializationJSONObjectWithData:dataoptions:NSJSONReadingMutableContainerserror:nil];

Type= [_testDicsvalueForKey:@"Type"];

//在下面构造model

model= [[M1294_hwymp_SMalloc]init];

[doServiceContainerInstance].SingletonModuleFactory=  [[doModuleFactoryalloc]init:model];

//如果是UI类型,还需要构造view

//UIView* view = [[xxxxView alloc]init];

}

- (void)ConfigUI {

CGFloatw =self.view.frame.size.width;

CGFloath =self.view.frame.size.height;

//在对应的测试按钮添加自己的测试代码,如果6个测试按钮不够,可以自己添加

if([TypeisEqualToString:@"UI"]){

//和SM,MM不一样,UI类型还得添加自己的View,所以测试按钮都在底部

CGFloatheight = h/6;

CGFloatwidth = (w -35)/6;

for(inti =0;i<6;i++){

UIButton*test = [UIButtonbuttonWithType:UIButtonTypeCustom];

test.frame=CGRectMake(5*(i+1)+width*i, h-h/6, width, height);

NSString* title = [NSStringstringWithFormat:@"Test%d",i ];

[testsetTitle:titleforState:UIControlStateNormal];

SELcustomSelector =NSSelectorFromString([NSStringstringWithFormat:@"test%d:",i]);

[testaddTarget:selfaction:customSelectorforControlEvents:UIControlEventTouchUpInside];

[self.viewaddSubview:test];

}

//addsubview自定义的UI

}else{

CGFloatheight = (h-140)/6;

CGFloatwidth = w -60;

for(inti =0;i<6;i++){

UIButton*test = [UIButtonbuttonWithType:UIButtonTypeCustom];

test.frame=CGRectMake(30,20*(i+1)+height*i, width, height);

NSString* title = [NSStringstringWithFormat:@"Test%d",i ];

[testsetTitle:titleforState:UIControlStateNormal];

SELcustomSelector =NSSelectorFromString([NSStringstringWithFormat:@"test%d:",i]);

[testaddTarget:selfaction:customSelectorforControlEvents:UIControlEventTouchUpInside];

[self.viewaddSubview:test];

}

}

}

- (void)test0:(UIButton*)sender

{

NSLog(@"请添加自己的测试代码");

}

- (void)test1:(UIButton*)sender

{

NSLog(@"请添加自己的测试代码");

//执行同步方法

//NSMutableDictionary* node = [[NSMutableDictionary alloc]init];

//[node setObject:参数值forKey:参数名];

//[[doService Instance] SyncMethod:model :同步方法名:node];

}

- (void)test2:(UIButton*)sender

{

NSLog(@"请添加自己的测试代码");

//执行异步方法

NSMutableDictionary* node = [[NSMutableDictionaryalloc]init];

[nodesetObject:@"/var/mobile/Containers/Data/Application/8F26712D-29F1-46F8-93FD-144D606E0342/Library/deviceone/data/1ea276f4-2fb8-4c03-8c0c-2c43f14c0b5d/temp/do_Album/BF74D875-7B19-44F5-9D88-40F3254BA5D4.jpg"forKey:@"imgUrl"];

CallBackEvnet* event = [[CallBackEvnetalloc]init];//回调类

[[doServiceInstance]AsyncMethod:model:@"getInfo":node:event];

}

- (void)test3:(UIButton*)sender

{

NSLog(@"请添加自己的测试代码");

}

- (void)test4:(UIButton*)sender

{

NSLog(@"请添加自己的测试代码");

}

- (void)test5:(UIButton*)sender

{

NSLog(@"请添加自己的测试代码");

}

- (void)didReceiveMemoryWarning {

[superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

上面蓝色部分为我添加的代码,直接在手机上面真是运行就可以了。

上面就是编码完成了。

7.上传zip包

经过步骤6的工作,我们下一步就是上传zip包到deviceone开发者后台的组件开发里面。

下面还是通过两个平台来讲解。

android:

我们看到在组件项目中有一个do_build.xml文件,打开,然后修改sdk版本路径。

然后点击右键的ant  build。就可以打包出来上传的zip包。

ios:

直接上图

通过这个编译之后,会有一个.a文件生成,然后将这个。a文件拷贝到一个文件夹下面

然后在拷贝下图文件

整理好的文件如下列表

hwymp.a

hwymp.plist

M1294_hwymp_App.h

M1294_hwymp_SM.h

四个文件。将这四个文件压缩成一个zip就可以了。

我们上传到android和ios各自平台上即可。

8.编写示例进行调试

打开deviceone的eclipse的开发工具。

创建一个项目。(这个略过)

然后去后台配置这个项目(略过)

然后配置组件,选择自己开发的内部组件,选择。(省略)

然后回到eclipse开发工具,同步组件(省略)

接下来开发

接下来看js的代码。

var nf = sm("do_Notification");

var album = sm("do_Album");

var hw = sm("M1294_hwymp");

var page = sm("do_Page");

var app = sm("do_App");

var file = sm("do_Storage");

page.on("back", function(data) {

app.closePage();

})

var select = ui("select");

select.on("touch", function() {

album.select(1, -1, -1, 100, false, function(data, e) {

select.source = data[0];

})

});

var btn = ui("btn");

btn.on("touch", function() {

hw.getInfo(select.source + "", function(data, e) {

nf.alert(JSON.stringify(data));

})

});

整个的思路就是,

我用一个imageview来看我选择的图片

我用一个album来选择图片并返回路径

我用一个button来控制识别

这样我的demo就完成了

9.完成。

下载安装调试版本的安装包。(省略)

点击更新。

调试出结果。OK

感谢大家。谢谢。

php 汉王云名片_汉王云名片识别(SM)组件开发详解相关推荐

  1. 汉王云名片识别(SM)组件开发详解

    大家好,最近在DeviceOne平台上做了一个汉王云名片识别的功能组件.下面把我开发过程给大家做一个分享,希望可以帮助到大家. 下面我把我的思路给大家讲解一下. 1.找到我要集成的sdk,也就是汉王云 ...

  2. nc65数据字典 云盘_从搜索引擎到核心交易数据库,详解阿里云神龙如何支撑双11...

    2020年的双11,天猫又创造了新的纪录:订单峰值达到创纪录的58.3万笔/秒,销售额达到历史新高4982亿,阿里云神龙再次成功扛住了全球流量洪峰.2020年是双11全面云原生化的第一年,也是神龙架构 ...

  3. 数据仓库电商建模_真实电商数据仓库全流程开发详解,资源教程下载

    课程名称 Hadoop大数据视频教程-第一季:真实电商数据仓库全流程开发详解(共46讲),资源教程下载 课程目录 第一部分:数据仓库基础理论与技术圈 第一章:互联网电商大数据环境 第二章:商业智能与数 ...

  4. 滴滴云A100 GPU裸金属服务器性能及硬件参数详解

    滴滴云A100 GPU裸金属服务器(BMS)是基于NVIDIA A100 GPU推出的公有云裸金属服务器产品,NVIDIA A100 Tensor Core GPU基于最新的Ampere架构,相比上一 ...

  5. 云渲染一张图贵吗?渲染问题详解

    我们知道使用云渲染可以个高效快捷的渲染工程项目文件,节省很多时间,广受CG行业人员的喜爱,而且也相信有很多小伙伴经常会有疑问:云渲染一张图多钱?今天,就随云渲染小编一起来了解清楚这些问题... 一.云 ...

  6. 阿里云国际版设置DNS托管和智能分流教程详解

    Domain Name System 是一个在阿里上的DNS托管工具,每家云端都有自己的DNS解析服务,阿里云有一项其他云端没有的特殊功能「URL隐性转发」,用户在点击你的网站时上方秀出的是A域名,但 ...

  7. C++框架_之Qt的信号和槽的详解

    目录 C++_之Qt的信号和槽的详解 1.概述 1.1对象树(子对象动态分配空间不需要释放) 2.信号和槽 Qt5 的书写方式:(推荐的使用)★★★★★ Qt4 的书写方式: 3.自定义信号槽 3.1 ...

  8. 计算机主板一直滴滴响,主板报警声大全_主板一直滴滴滴短响含义详解

    主板报警声大全_主板一直滴滴滴短响含义详解 在电脑使用过程中,有时我们会听到电脑主板发出类似报警的声音,这时候说明可能电脑主板出现了一定的问题,电脑主板报警的原因有很多,我们可以从报警的声音去区分到底 ...

  9. php 汉王云名片_汉王开发者中心

    汉王云介绍 汉王云是一个开放的平台,她是提供识别服务的,也可以称作汉王识别云.汉王云致力于为中小微初创企业.大客户企业提供在线的文字图像识别API,为广大互联网用户提供在线的便利的文字识别转化服务.汉 ...

最新文章

  1. Matlab与线性代数 -- 魔方矩阵
  2. 0x03.基本算法 — 前缀和与差分
  3. CentOS下安装JDK的三种方法
  4. linux下踢出已登录用户
  5. SAP附件清单的调用
  6. taylor级数 matlab,Taylor级数与Fourier级数展开式比较与MATLAB实例.docx
  7. mysql文献综述_文献综述随笔(二十)
  8. 使用SafeViewFlipper避免ViewFlipper交替时Crash
  9. swoole mysql 连接数_用swoole简单实现MySQL连接池
  10. 容器安全 - 以只读方式运行容器
  11. 在vSphere 6.x vSAN数据存储上使用Oracle RAC(2121181)
  12. sql 2005性能调优
  13. java破坏双亲委派_java的类加载机制-双亲委派,破坏双亲委派
  14. linear-gradient常用实现效果
  15. 同步IO和异步IO的理解
  16. jdbc mysql emoji 读取_mysql/Java服务端对emoji的支持
  17. 图灵——如迷的解谜者
  18. PDF.js使用教程
  19. 群晖docker火狐_群晖 篇一:群晖Docker下搭建ubuntu开发环境
  20. struts2 xml 验证出现 Invalid field value for field 的解决方法(转)

热门文章

  1. 【21天习惯养成记~~day17晚】
  2. IPV6地址基础知识
  3. php 应用截图,PHP应用:php使用CutyCapt实现网页截图保存的方法
  4. 虚拟机无法ping通物理机解决方案
  5. 论文笔记目录(ver2.0)
  6. JavaScript中Object.entries(obj)
  7. 【AnimeJs】——仿Animejs徒手实现SVG动画
  8. 2.1 zio入门——把函数作用作为工作蓝图
  9. python输入百分制成绩s、按五级分制输出_输入一个百分制成绩,利用switch语句编写程序,要求输出成绩等级A B C D,E。90以上为A...
  10. SCI、SCI期刊与SCI论文的区别