Android端直接调用

视觉智能开放平台的API接口推荐使用SDK进行调用,推荐在服务端进行接入,在客户端直接接入AccessKey ID和AccessKey Secret有泄露风险,可以使用STS授权用户调用服务。

背景信息

使用小程序调用之前,需要使用STS服务获取临时访问凭证。阿里云STS(Security Token Service)是阿里云提供的一种临时访问权限管理服务。您可以通过STS服务给其他用户颁发临时访问凭证,该用户可使用临时访问凭证,在规定时间内调用视觉智能开放平台的各项服务。临时访问凭证无需透露您的长期密钥,保障您的账户更加安全。获取临时访问凭证,请参见获取角色的临时身份凭证

说明

阿里云视觉智能开放平台提供各类目视觉AI能力API接入、接口使用或问题咨询等,请通过钉钉群(23109592)加入阿里云视觉智能开放平台咨询群联系我们。

前提条件

获取STS临时凭证:

  1. 授予权限

    在获取STS临时凭证之前,调用者(RAM用户和RAM角色)需要被授权有调用STS接口的权限。您可以通过设置RAM权限策略来实现这一点。相关的设置步骤和权限策略可参见使用STS临时访问凭证访问OSS文档。您需要根据实际需求配置更细粒度的授权策略,防止出现权限过大的风险。关于更细粒度的授权策略配置详情,请参见视觉智能开放平台自定义权限策略参考

    重要

    为进行后续步骤,调用者(RAM用户和RAM角色)需要被授权:

    • AliyunSTSAssumeRoleAccess(调用STS服务AssumeRole接口的权限)。

    • AliyunVIAPIFullAccess(这里为了下列实例,给出的是管理视觉智能API的权限,但是在实际工作中,强烈建议您根据实际需求配置更细粒度的授权策略,防止出现权限过大的风险。关于更细粒度的授权策略配置详情,请参见视觉智能开放平台自定义权限策略参考)。

  2. 调用AssumeRole接口

    使用已授权的RAM用户或RAM角色调用AssumeRole接口,并按照接口文档填写必要参数。请参见AssumeRole文档。

  3. 使用STS Token

    调用AssumeRole接口成功后,您会收到一个包含AccessKeyIdAccessKeySecretSecurityToken的STS Token(如下代码)。

    在实际调用其他阿里云服务的接口时,您需要将代码中的<ALIBABA_CLOUD_ACCESS_KEY_ID><ALIBABA_CLOUD_ACCESS_KEY_SECRET><ALIBABA_CLOUD_SECURITY_TOKEN>替换为阿里云STS Token数据中获取的临时AccessKeyIdAccessKeySecretSecurityToken

    {
      "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端直接调用,可以参考Java SDK调用,支持本地文件和任意URL。

说明

由于安卓存在线程机制,不能在主线程直接发起调用,请在子线程调用。

本文以银行卡识别(RecognizeBankCard)为例,仅展示关键步骤和代码,完整的示例可下载AndroidDemo。您如果调用其他算法,请参考注释和实际业务修改相应代码。

在应用的build.gradle文件中添加依赖

// 1、see https://help.aliyun.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包,您需要根据自己的实际业务引入Java SDK包。Java SDK包的详情,请参见Java SDK

初始化Client

重要

在实际调用其他阿里云服务的接口时,您需要将代码中的<ALIBABA_CLOUD_ACCESS_KEY_ID><ALIBABA_CLOUD_ACCESS_KEY_SECRET><ALIBABA_CLOUD_SECURITY_TOKEN>替换为阿里云STS Token数据中获取的临时AccessKeyIdAccessKeySecretSecurityToken

// 代码中的<ALIBABA_CLOUD_ACCESS_KEY_ID>、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>、<ALIBABA_CLOUD_SECURITY_TOKEN>
// 需替换为阿里云STS Token数据中获取的临时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、访问的域名。注意:这个地方需要求改为相应类目的域名,参考:https://help.aliyun.com/document_detail/143103.html
config.endpoint = "ocr.cn-shanghai.aliyuncs.com";
client = new Client(config);

调用API

场景一:文件在上海地域OSS

/**
 * 文件在上海地域OSS,调用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为例,其他能力请使用相应类目的包和类,具体入参设置需要参考具体能力的文档
                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);
                // 获取整体结果。部分能力会输出url链接,通过toJSONString转换后可能有编码问题,但是通过单个字段获取是没问题的。
                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("调用成功,银行卡号:" + resp.getBody().getData().getCardNumber());
            } catch (com.aliyun.tea.TeaException teaException) {
                Log.d(TAG, "teaException.getCode(): " + teaException.getCode());
                // 请处理Exception
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
            }
        }
    }).start();
说明

此场景需要APP访问网络的权限,请确保已配置APP访问网络的权限。

场景二:文件在本地

/**
 * 文件在本地,调用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下的文件如何转为stream,如果文件来自其他地方,如sdcard或者摄像头,请自行查看android开发文档或教程将文件转为stream之后传入。
                InputStream inputStream = MainActivity.this.getAssets().open(filePath);
                // 4、这里只是以ocr下的RecognizeBankCard为例,其他能力请使用相应类目的包和类,具体入参设置需要参考具体能力的文档
                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);
                // 获取整体结果。部分能力会输出url链接,通过toJSONString转换后可能有编码问题,但是通过单个字段获取是没问题的。
                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("调用成功,银行卡号:" + resp.getBody().getData().getCardNumber());
            } catch (com.aliyun.tea.TeaException teaException) {
                Log.d(TAG, "teaException.getCode(): " + teaException.getCode());
                // 请处理Exception
            } catch (java.io.FileNotFoundException e) {
                showToastMsg("文件找不到,请检查代码中的filePath路径是否正确");
                Log.e(TAG, e.getMessage());
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
            }
        }
    }).start();

}
说明

此场景需要APP访问网络和本地文件的权限,请在确保已配置APP访问网络和本地文件的权限。

场景三:文件在任意可访问的URL

/**
 * 文件在任意URL,调用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为例,其他能力请使用相应类目的包和类,具体入参设置需要参考具体能力的文档
                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);
                // 获取整体结果。部分能力会输出url链接,通过toJSONString转换后可能有编码问题,但是通过单个字段获取是没问题的。
                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("调用成功,银行卡号:" + resp.getBody().getData().getCardNumber());
            } catch (com.aliyun.tea.TeaException teaException) {
                Log.d(TAG, "teaException.getCode(): " + teaException.getCode());
                // 请处理Exception
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
            }
        }
    }).start();

}
说明

此场景需要APP访问网络并且需要支持访问HTTP链接的权限,请确保已配置APP访问网络的权限并支持访问HTTP链接。

完整工程仅以银行卡识别(RecognizeBankCard)为例,如果调用其他算法,请参考注释进行相应代码修改。

修改点可参见Java SDK,总结如下:

  1. 引入包的时候,需要引入相应类目的包和相关类。包括build.gradle中的com.aliyun:ocr20191230:1.0.23和MainActivity.java中import。包名可参考Java SDK包名称,能力名称可参考对应API文档中的Action参数。

    例如,您想使用通用分割能力,通过通用分割API文档可知该能力属于分割抠图类目(imageseg20191230),能力名称为SegmentCommonImage,您需要将代码中的ocr20191230改为imageseg20191230,将RecognizeBankCard改为SegmentCommonImage。

  2. 访问的域名一定要修改为相应类目的域名,如果域名类目不匹配会报错InvalidAction.NotFound。关于域名详情,请参见访问域名

  3. Request和Response需要使用相应类目的包和类。

  4. 调用Client的方法时,方法名需要改成对应能力的方法名。方法名是根据能力名称按照一定规范形成的。例如,能力名称为SegmentCommonImage,文件在上海地域OSS对应方法名应该为segmentCommonImageWithOptions,文件在本地或可访问的URL对应方法名应该为segmentCommonImageAdvance。