Android端直接調(diào)用
視覺智能開放平臺的API接口推薦使用SDK進行調(diào)用,推薦在服務(wù)端進行接入,在客戶端直接接入AccessKey ID和AccessKey Secret有泄露風險,可以使用STS授權(quán)用戶調(diào)用服務(wù)。
背景信息
使用小程序調(diào)用之前,需要使用STS服務(wù)獲取臨時訪問憑證。阿里云STS(Security Token Service)是阿里云提供的一種臨時訪問權(quán)限管理服務(wù)。您可以通過STS服務(wù)給其他用戶頒發(fā)臨時訪問憑證,該用戶可使用臨時訪問憑證,在規(guī)定時間內(nèi)調(diào)用視覺智能開放平臺的各項服務(wù)。臨時訪問憑證無需透露您的長期密鑰,保障您的賬戶更加安全。獲取臨時訪問憑證,請參見獲取角色的臨時身份憑證。
阿里云視覺智能開放平臺提供各類目視覺AI能力API接入、接口使用或問題咨詢等,請通過釘釘群(23109592)加入阿里云視覺智能開放平臺咨詢?nèi)郝?lián)系我們。
前提條件
獲取STS臨時憑證:
授予權(quán)限
在獲取STS臨時憑證之前,調(diào)用者(RAM用戶和RAM角色)需要被授權(quán)有調(diào)用STS接口的權(quán)限。您可以通過設(shè)置RAM權(quán)限策略來實現(xiàn)這一點。相關(guān)的設(shè)置步驟和權(quán)限策略可參見使用STS臨時訪問憑證訪問OSS文檔。您需要根據(jù)實際需求配置更細粒度的授權(quán)策略,防止出現(xiàn)權(quán)限過大的風險。關(guān)于更細粒度的授權(quán)策略配置詳情,請參見視覺智能開放平臺自定義權(quán)限策略參考。
重要為進行后續(xù)步驟,調(diào)用者(RAM用戶和RAM角色)需要被授權(quán):
AliyunSTSAssumeRoleAccess(調(diào)用STS服務(wù)AssumeRole接口的權(quán)限)。
AliyunVIAPIFullAccess(這里為了下列實例,給出的是管理視覺智能API的權(quán)限,但是在實際工作中,強烈建議您根據(jù)實際需求配置更細粒度的授權(quán)策略,防止出現(xiàn)權(quán)限過大的風險。關(guān)于更細粒度的授權(quán)策略配置詳情,請參見視覺智能開放平臺自定義權(quán)限策略參考)。
調(diào)用AssumeRole接口
使用已授權(quán)的RAM用戶或RAM角色調(diào)用AssumeRole接口,并按照接口文檔填寫必要參數(shù)。請參見AssumeRole文檔。
使用STS Token
調(diào)用AssumeRole接口成功后,您會收到一個包含
AccessKeyId
、AccessKeySecret
和SecurityToken
的STS Token(如下代碼)。在實際調(diào)用其他阿里云服務(wù)的接口時,您需要將代碼中的
<ALIBABA_CLOUD_ACCESS_KEY_ID>
、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
、<ALIBABA_CLOUD_SECURITY_TOKEN>
替換為阿里云STS Token數(shù)據(jù)中獲取的臨時AccessKeyId
、AccessKeySecret
、SecurityToken
。{ "RequestId": "429D9967-C809-5A30-B65E-9B742CF*****", "AssumedRoleUser": { "Arn": "acs:ram::175805416243****:role/STStokenTestRole/STSsessionName", "AssumedRoleId": "39779315882322****:STSsessionName" }, "Credentials": { "SecurityToken": "exampleToken", "AccessKeyId": "STS.exampleAccessKeyID", "AccessKeySecret": "exampleAccessKeySecret", "Expiration": "2024-06-12T03:21:29Z" } }
SDK示例
使用Android端直接調(diào)用,可以參考Java SDK調(diào)用,支持本地文件和任意URL。
由于安卓存在線程機制,不能在主線程直接發(fā)起調(diào)用,請在子線程調(diào)用。
本文以銀行卡識別(RecognizeBankCard)為例,僅展示關(guān)鍵步驟和代碼,完整的示例可下載AndroidDemo。您如果調(diào)用其他算法,請參考注釋和實際業(yè)務(wù)修改相應代碼。
在應用的build.gradle文件中添加依賴
// 1、see http://bestwisewords.com/document_detail/153132.html for sdk
implementation("com.aliyun:ocr20191230:1.0.23") {
exclude group: 'xml-apis', module: 'xml-apis'
exclude group: 'dom4j', module: 'dom4j'
}
本文以銀行卡識別(RecognizeBankCard)為例,因此引入了OCR包,您需要根據(jù)自己的實際業(yè)務(wù)引入Java SDK包。Java SDK包的詳情,請參見Java SDK。
初始化Client
在實際調(diào)用其他阿里云服務(wù)的接口時,您需要將代碼中的<ALIBABA_CLOUD_ACCESS_KEY_ID>
、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
、<ALIBABA_CLOUD_SECURITY_TOKEN>
替換為阿里云STS Token數(shù)據(jù)中獲取的臨時AccessKeyId
、AccessKeySecret
、SecurityToken
。
// 代碼中的<ALIBABA_CLOUD_ACCESS_KEY_ID>、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>、<ALIBABA_CLOUD_SECURITY_TOKEN>
// 需替換為阿里云STS Token數(shù)據(jù)中獲取的臨時AccessKeyId、AccessKeySecret、SecurityToken
String accessKeyId = "<ALIBABA_CLOUD_ACCESS_KEY_ID>";
String accessKeySecret = "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>";
String securityToken = "<ALIBABA_CLOUD_SECURITY_TOKEN>";
Config config = new Config()
//AccessKeyID
.setAccessKeyId(accessKeyId)
//AccessKeySecret
.setAccessKeySecret(accessKeySecret)
//SecurityToken
.setSecurityToken(securityToken);
// 3、訪問的域名。注意:這個地方需要求改為相應類目的域名,參考:http://bestwisewords.com/document_detail/143103.html
config.endpoint = "ocr.cn-shanghai.aliyuncs.com";
client = new Client(config);
調(diào)用API
場景一:文件在上海地域OSS
/**
* 文件在上海地域OSS,調(diào)用API,以RecognizeBankCard為例。
* @param view
*/
public void callApiShanghaiOss(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Log.d(TAG, String.format("begin callApi: %s %s", "RecognizeBankCard", "http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeBankCard/yhk1.jpg"));
// 4、這里只是以ocr下的RecognizeBankCard為例,其他能力請使用相應類目的包和類,具體入?yún)⒃O(shè)置需要參考具體能力的文檔
com.aliyun.ocr20191230.models.RecognizeBankCardRequest recognizeBankCardRequest = new com.aliyun.ocr20191230.models.RecognizeBankCardRequest()
.setImageURL("http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeBankCard/yhk1.jpg");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
// 5、這里只是以ocr下的RecognizeBankCard為例,其他能力請使用相應類目的包和類,注意,recognizeBankCardWithOptions方法名也需要改成對應能力的方法名
RecognizeBankCardResponse resp = client.recognizeBankCardWithOptions(recognizeBankCardRequest, runtime);
// 獲取整體結(jié)果。部分能力會輸出url鏈接,通過toJSONString轉(zhuǎn)換后可能有編碼問題,但是通過單個字段獲取是沒問題的。
Log.d(TAG, String.format("%s", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp))));
// 獲取單個字段,這里只是一個例子,具體能力下的字段需要看具體能力的文檔
Log.d(TAG, String.format("%s", resp.getBody().getData().getCardNumber()));
showToastMsg("調(diào)用成功,銀行卡號:" + resp.getBody().getData().getCardNumber());
} catch (com.aliyun.tea.TeaException teaException) {
Log.d(TAG, "teaException.getCode(): " + teaException.getCode());
// 請?zhí)幚鞥xception
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
}
}).start();
此場景需要APP訪問網(wǎng)絡(luò)的權(quán)限,請確保已配置APP訪問網(wǎng)絡(luò)的權(quán)限。
場景二:文件在本地
/**
* 文件在本地,調(diào)用API,以RecognizeBankCard為例。
* @param view
*/
public void callApiLocal(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
// filePath請改成您的真實文件路徑
String filePath = "resource/test_images/yhk1.jpg";
Log.d(TAG, String.format("begin callApi: %s %s", "RecognizeBankCard", filePath));
// 使用文件,文件通過inputStream傳入接口。這里只是演示了assets下的文件如何轉(zhuǎn)為stream,如果文件來自其他地方,如sdcard或者攝像頭,請自行查看android開發(fā)文檔或教程將文件轉(zhuǎn)為stream之后傳入。
InputStream inputStream = MainActivity.this.getAssets().open(filePath);
// 4、這里只是以ocr下的RecognizeBankCard為例,其他能力請使用相應類目的包和類,具體入?yún)⒃O(shè)置需要參考具體能力的文檔
com.aliyun.ocr20191230.models.RecognizeBankCardAdvanceRequest recognizeBankCardAdvanceRequest = new com.aliyun.ocr20191230.models.RecognizeBankCardAdvanceRequest()
.setImageURLObject(inputStream);
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
// 5、這里只是以ocr下的RecognizeBankCard為例,其他能力請使用相應類目的包和類,注意,recognizeBankCardAdvance方法名也需要改成對應能力的方法名
RecognizeBankCardResponse resp = client.recognizeBankCardAdvance(recognizeBankCardAdvanceRequest, runtime);
// 獲取整體結(jié)果。部分能力會輸出url鏈接,通過toJSONString轉(zhuǎn)換后可能有編碼問題,但是通過單個字段獲取是沒問題的。
Log.d(TAG, String.format("%s", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp))));
// 獲取單個字段,這里只是一個例子,具體能力下的字段需要看具體能力的文檔
Log.d(TAG, String.format("%s", resp.getBody().getData().getCardNumber()));
showToastMsg("調(diào)用成功,銀行卡號:" + resp.getBody().getData().getCardNumber());
} catch (com.aliyun.tea.TeaException teaException) {
Log.d(TAG, "teaException.getCode(): " + teaException.getCode());
// 請?zhí)幚鞥xception
} catch (java.io.FileNotFoundException e) {
showToastMsg("文件找不到,請檢查代碼中的filePath路徑是否正確");
Log.e(TAG, e.getMessage());
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
}
}).start();
}
此場景需要APP訪問網(wǎng)絡(luò)和本地文件的權(quán)限,請在確保已配置APP訪問網(wǎng)絡(luò)和本地文件的權(quán)限。
場景三:文件在任意可訪問的URL
/**
* 文件在任意URL,調(diào)用API,以RecognizeBankCard為例。
* @param view
*/
public void callApiAnyUrl(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Log.d(TAG, String.format("begin callApi: %s %s", "RecognizeBankCard", "https://viapi-test-bj.oss-cn-beijing.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeBankCard/yhk1.jpg"));
// 使用任意URL
URL url = new URL("https://viapi-test-bj.oss-cn-beijing.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeBankCard/yhk1.jpg");
InputStream inputStream = url.openConnection().getInputStream();
// 4、這里只是以ocr下的RecognizeBankCard為例,其他能力請使用相應類目的包和類,具體入?yún)⒃O(shè)置需要參考具體能力的文檔
com.aliyun.ocr20191230.models.RecognizeBankCardAdvanceRequest recognizeBankCardAdvanceRequest = new com.aliyun.ocr20191230.models.RecognizeBankCardAdvanceRequest()
.setImageURLObject(inputStream);
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
// 5、這里只是以ocr下的RecognizeBankCard為例,其他能力請使用相應類目的包和類,注意,recognizeBankCardAdvance方法名也需要改成對應能力的方法名
RecognizeBankCardResponse resp = client.recognizeBankCardAdvance(recognizeBankCardAdvanceRequest, runtime);
// 獲取整體結(jié)果。部分能力會輸出url鏈接,通過toJSONString轉(zhuǎn)換后可能有編碼問題,但是通過單個字段獲取是沒問題的。
Log.d(TAG, String.format("%s", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp))));
// 獲取單個字段,這里只是一個例子,具體能力下的字段需要看具體能力的文檔
Log.d(TAG, String.format("%s", resp.getBody().getData().getCardNumber()));
showToastMsg("調(diào)用成功,銀行卡號:" + resp.getBody().getData().getCardNumber());
} catch (com.aliyun.tea.TeaException teaException) {
Log.d(TAG, "teaException.getCode(): " + teaException.getCode());
// 請?zhí)幚鞥xception
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
}
}).start();
}
此場景需要APP訪問網(wǎng)絡(luò)并且需要支持訪問HTTP鏈接的權(quán)限,請確保已配置APP訪問網(wǎng)絡(luò)的權(quán)限并支持訪問HTTP鏈接。
完整工程僅以銀行卡識別(RecognizeBankCard)為例,如果調(diào)用其他算法,請參考注釋進行相應代碼修改。
修改點可參見Java SDK,總結(jié)如下:
引入包的時候,需要引入相應類目的包和相關(guān)類。包括build.gradle中的com.aliyun:ocr20191230:1.0.23和MainActivity.java中import。包名可參考Java SDK包名稱,能力名稱可參考對應API文檔中的Action參數(shù)。
例如,您想使用通用分割能力,通過通用分割API文檔可知該能力屬于分割摳圖類目(imageseg20191230),能力名稱為SegmentCommonImage,您需要將代碼中的ocr20191230改為imageseg20191230,將RecognizeBankCard改為SegmentCommonImage。
訪問的域名一定要修改為相應類目的域名,如果域名類目不匹配會報錯
InvalidAction.NotFound
。關(guān)于域名詳情,請參見訪問域名。Request和Response需要使用相應類目的包和類。
調(diào)用Client的方法時,方法名需要改成對應能力的方法名。方法名是根據(jù)能力名稱按照一定規(guī)范形成的。例如,能力名稱為SegmentCommonImage,文件在上海地域OSS對應方法名應該為segmentCommonImageWithOptions,文件在本地或可訪問的URL對應方法名應該為segmentCommonImageAdvance。