引言
用四个小时接入一个百度OCR-SDK,是种什么样的体验,总之很开心哈哈,周六撸代码撸到了半夜一点多,给自己点赞。我从刚开始接入第一个第三方SDK的苦大仇深,到现在随便接入SDK的打怪升级,获得了诸多成长和收获。在此也感谢fans们的留言,让我得以更快的成长,未来一起学习,共同进步!
国际惯例,先上成品效果。
闲言少叙,首先来介绍一下OCR是什么,这是百度提供的一套根据拍摄图片识别图中文字的SDK。提供了多个API接口。截图不全,具体请走下方传送门去官方文档看详细介绍:
传送门->接入OCR-SDK官方文档
传送门->百度开发平台
第一步:根据开发文档创建Key并关联Application应用
根据官方文档中提供的COR-SDK的demo下载试运行,之后在百度开放平台中创建自己的Applicatiion应用,包括apiKey,secretKey的确定,以及提供Application包名与AK、SK进行关联。
Tips:开发文档中都有,我就不做赘述了,接下来讲如何将第三方SDK集成到自己的项目中去。
第二步:进入应用管理页面下载SDK准备接入
下载完成后解压可看到:
第三步:运行OCRDemo并完成gradle配置
接入SDK最重要的,是首先要跑起来demo文件,如果demo文件都跑不起来,怎么做都是徒劳,这一点望谨记,遇到问题要想办法解决问题,而非逃避问题。
我的Mydemo例子Application中如下配置:(可参考但无须雷同,一切以跑起来sdk的demo文件为目的!!!)
第四步:引入SDK的jar包
直接从运行起来的demo中进行拷贝libs下的文件到自己的应用中
第五步:在Activity中尝试调用SDK
public class Case72 extends AppCompatActivity {
private String apiKey = "wW3adgdDIfMwN8oia31perDR";
private String secretKey = "GjESpGef8OOjtqUb5Ttok6o9GhgmpNEU";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_case72);
//测试是否能成功调用SDK
initSDKTest();
}
/**
* 用明文ak,sk初始化
*/
private void initSDKTest() {
OCR.getInstance(this).initAccessTokenWithAkSk(new OnResultListener() {
@Override
public void onResult(AccessToken result) {
String token = result.getAccessToken();
Log.d("result-->", "成功!" + token);
}
@Override
public void onError(OCRError error) {
error.printStackTrace();
Log.d("result-->", "失败!" + error.getMessage());
}
}, getApplicationContext(), apiKey, secretKey);
}
}
出现下面的log则说明初步接通了SDK
2021-02-28 11:03:15.685 29657-30194/com.example.mydemo D/result-->: 成功!24.153158ed762cbd6b3664a6d2fa09d178.2592000.1617029403.282335-23718286
Tips:每个人创建的应用明秘文ApiKey,SecretKey不同,不要照搬,要换成自己在平台创建应用后生成的!
第六步:根据AK、SK获取Token
public class Case72 extends AppCompatActivity {
private String apiKey = "wW3adgdDIfMwN8oia31perDR";
private String secretKey = "GjESpGef8OOjtqUb5Ttok6o9GhgmpNEU";
private boolean hasGotToken = false;
private AlertDialog.Builder alertDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_case72);
//测试是否能成功调用SDK
initSDKTest();
//选择明秘文方式获取Token
initAccessTokenWithAkSk();
}
/**
* 用明文ak,sk初始化
*/
private void initSDKTest() {
OCR.getInstance(this).initAccessTokenWithAkSk(new OnResultListener() {
@Override
public void onResult(AccessToken result) {
String token = result.getAccessToken();
Log.d("result-->", "成功!" + token);
}
@Override
public void onError(OCRError error) {
error.printStackTrace();
Log.d("result-->", "失败!" + error.getMessage());
}
}, getApplicationContext(), apiKey, secretKey);
}
/**
* 用明文ak,sk初始化
*/
private void initAccessTokenWithAkSk() {
OCR.getInstance(this).initAccessTokenWithAkSk(new OnResultListener() {
@Override
public void onResult(AccessToken result) {
String token = result.getAccessToken();
hasGotToken = true;
}
@Override
public void onError(OCRError error) {
error.printStackTrace();
Log.d("打印==: ", error.getMessage());
alertText("AK,SK方式获取token失败", error.getMessage());
}
//}, getApplicationContext(), "请填入您的AK", "请填入您的SK");
}, getApplicationContext(), apiKey, secretKey);
}
private void alertText(final String title, final String message) {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
alertDialog.setTitle(title)
.setMessage(message)
.setPositiveButton("确定", null)
.show();
}
});
}
}
Tips:这一步只要不谈出提醒框就证明获取成功。
第七步:引入ocr_ui模块,完成接口调用
(1)首先,去找下载的SDK解压缩后的包中的
(2)然后,在AndroidStudio中导入模块
(3)之后,我们的app同级目录下会出现ocr_ui的library
(4)最后,在Activity完成接口调用功能逻辑代码。
public class Case72 extends AppCompatActivity {
private String apiKey = "wW3adgdDIfMwN8oia31perDR";
private String secretKey = "GjESpGef8OOjtqUb5Ttok6o9GhgmpNEU";
private boolean hasGotToken = false;
private static final int REQUEST_CODE_ACCURATE_BASIC = 107;
private AlertDialog.Builder alertDialog;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_case72);
//测试是否能成功调用SDK
initSDKTest();
mTextView = findViewById(R.id.tvShow);
findViewById(R.id.btnShow).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//呼出第三方SDK_Ui模块
if (!checkTokenStatus()) {
return;
}
Intent intent = new Intent(Case72.this, CameraActivity.class);
intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH,
FileUtil.getSaveFile(getApplication()).getAbsolutePath());
intent.putExtra(CameraActivity.KEY_CONTENT_TYPE,
CameraActivity.CONTENT_TYPE_GENERAL);
startActivityForResult(intent, REQUEST_CODE_ACCURATE_BASIC);
}
});
//选择明秘文方式获取Token
initAccessTokenWithAkSk();
}
/**
* 用明文ak,sk初始化
*/
private void initSDKTest() {
OCR.getInstance(this).initAccessTokenWithAkSk(new OnResultListener() {
@Override
public void onResult(AccessToken result) {
String token = result.getAccessToken();
Log.d("result-->", "成功!" + token);
}
@Override
public void onError(OCRError error) {
error.printStackTrace();
Log.d("result-->", "失败!" + error.getMessage());
}
}, getApplicationContext(), apiKey, secretKey);
}
/**
* 用明文ak,sk初始化
*/
private void initAccessTokenWithAkSk() {
OCR.getInstance(this).initAccessTokenWithAkSk(new OnResultListener() {
@Override
public void onResult(AccessToken result) {
String token = result.getAccessToken();
hasGotToken = true;
}
@Override
public void onError(OCRError error) {
error.printStackTrace();
Log.d("打印==: ", error.getMessage());
alertText("AK,SK方式获取token失败", error.getMessage());
}
//}, getApplicationContext(), "请填入您的AK", "请填入您的SK");
}, getApplicationContext(), apiKey, secretKey);
}
private void alertText(final String title, final String message) {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
alertDialog.setTitle(title)
.setMessage(message)
.setPositiveButton("确定", null)
.show();
}
});
}
private boolean checkTokenStatus() {
if (!hasGotToken) {
Toast.makeText(getApplicationContext(), "token还未成功获取", Toast.LENGTH_LONG).show();
}
return hasGotToken;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initAccessTokenWithAkSk();
} else {
Toast.makeText(getApplicationContext(), "需要android.permission.READ_PHONE_STATE", Toast.LENGTH_LONG).show();
}
}
//
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// 识别成功回调,通用文字识别(高精度版)
if (requestCode == REQUEST_CODE_ACCURATE_BASIC && resultCode == Activity.RESULT_OK) {
RecognizeService.recAccurateBasic(this, FileUtil.getSaveFile(getApplicationContext()).getAbsolutePath(),
new RecognizeService.ServiceListener() {
@Override
public void onResult(String result) {
OCRResultBean dataBean = new Gson().fromJson(result, OCRResultBean.class);
StringBuilder sB = new StringBuilder();
for (OCRResultBean.WordsResultBean bean:dataBean.getWords_result()){
String str = bean.getWords();
Log.d("onResult==: ",str);
sB.append(str).append("\n");
}
mTextView.setText(sB.toString());
// Log.d("打印result==: ", sB.toString());
// Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show());
}
});
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 释放内存资源
OCR.getInstance(this).release();
}
}
Tips:布局文件很简单,一个Button,用来跳转到相机拍照页面,一个TextView,用来展示从接口获取到的图片文字信息。
期间,将接口拿到的直接json数据进行了gson解析,通过一个DataBean类:OCRResultBean完成解析过程,并且使用StringBuilder对象进行字符串的拼接和换行操作。(增强型for循环的经典使用场景哈哈)
哦,差点忘了!!!OCRResultBean
/**
* @data on 2/28/21 1:30 AM
* @auther armStrong759
* @describe 百度第三方SDK-OCR图片识别文字接入返回json转databean
*/
public class OCRResultBean {
/**
* log_id : 4694100800134148699
* direction : 0
* words_result_num : 3
* words_result : [{"words":" HERO"},{"words":" WARS"},{"words":"杀死地精"}]
*/
private long log_id;
private int direction;
private int words_result_num;
/**
* words : HERO
*/
private List words_result;
public long getLog_id() {
return log_id;
}
public void setLog_id(long log_id) {
this.log_id = log_id;
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
public int getWords_result_num() {
return words_result_num;
}
public void setWords_result_num(int words_result_num) {
this.words_result_num = words_result_num;
}
public List getWords_result() {
return words_result;
}
public void setWords_result(List words_result) {
this.words_result = words_result;
}
public static class WordsResultBean {
private String words;
public String getWords() {
return words;
}
public void setWords(String words) {
this.words = words;
}
}
}
附【源码地址】:https://github.com/Kingcool759/Mydemo.git
Tips:Case72哦!