安全私密图片

背景

借助“安全私密图片”功能,您可以定义卡券上无需通过面向公众的网址访问的图片(常规图片需要在卡券上正确呈现,因此必须通过面向公众的网址访问)。您可以使用 Wallet API 上传图片,并接收一个标识符,该标识符可用于在 Google 钱包卡券对象中引用相应图片。

支持以下卡券类型:

  • 活动门票
  • 登机牌
  • 公交卡
  • Offer Card
  • 礼品卡
  • 会员卡
  • 通用卡券

功能示例

安全私密图片示例
使用安全私密图片的会员卡

使用场景

安全私有映像可用于无需公开访问的映像,因此可用于个人资料照片等内容。这可实现以下用例,但不限于:

  • 包年会员卡
  • 名片
  • 公交卡

注意:安全私有映像不应用于表示通行证,也不应作为政府签发的身份证件使用,同时还应遵守使用政策中规定的其他准则

使用 Google 钱包功能时的一些注意事项

  • 不能与通用私人通行证一起使用
  • 只能添加到卡券对象(而非卡券类)
  • 只能与单个对象搭配使用
  • 只能与 ImageModuleData 搭配使用(不能与其他图片搭配使用,例如徽标和宽幅标题徽标)

开发中的功能

  • Web 支持
  • 主打图片中的私密图片

集成步骤

  1. 使用 Google Wallet API 上传您的私人图片,即可获得 privateImageId
  2. 向卡券对象(例如 ImageModuleData)添加图片。您将使用从上一步中获得的值设置 privateImageId 字段,而不是设置图片的 sourceUri 字段。

序列图

安全映像序列图
安全私密图片序列

示例代码

上传图片

String issuerId = "12345";
String keyFilePath = "/path/to/key.json";
GoogleCredential credential =
    GoogleCredential.fromStream(new FileInputStream(keyFilePath))
        .createScoped(Arrays.asList("https://www.googleapis.com/auth/wallet_object.issuer"));
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

// Prepare request to upload image
String contentType = "image/jpeg";  // MIME type of image
String imageFilePath = "/path/to/image.jpg";
HttpContent content =
    new ByteArrayContent(
        contentType, ByteStreams.toByteArray(new FileInputStream(imageFilePath)));

String url =
    String.format(
        "https://walletobjects.googleapis.com/upload/walletobjects/v1/privateContent/%s/uploadPrivateImage",
        issuerId);

// Make request to upload image
HttpResponse response =
    httpTransport
        .createRequestFactory(credential)
        .buildPostRequest(new GenericUrl(url), content)
        .execute();

// Get privateImageId from response
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(response.parseAsString(), JsonObject.class);
String privateImageId = jsonObject.get("privateImageId").getAsString();

在卡券对象上使用私有映像

// Build GenericObject with privateImageId in ImageModuleData (also adding an optional TextModuleData)
Image image = new Image().setPrivateImageId(privateImageId);
ImageModuleData imageModuleData = new ImageModuleData().setId("imageId").setMainImage(image);
TextModuleData textModuleData =
    new TextModuleData().setId("textId").setHeader("Card holder").setBody("John Doe");
GenericObject genericObject =
    new GenericObject()
        .setId(issuerId + ".objectId")
        // class must be inserted before inserting object
        .setClassId(issuerId + ".classId")
        .setCardTitle("Business name")
        .setHeader("My membership card")
        .setImageModulesData(Arrays.asList(imageModuleData))
        .setTextModulesData(Arrays.asList(textModuleData));

// Insert GenericObject (or can use in JWT without inserting ahead of time)
Walletobjects service =
    new Walletobjects.Builder(httpTransport, GsonFactory.getDefaultInstance(), credential)
        .setApplicationName("My Application")
        .build();

service.genericobject().insert(genericObject).execute();

更新通行卡以在正面显示图片

您可以在任何 imageModulesDatafield 中使用安全私密映像。 以下示例展示了如何使用 imageModulesData 字段通过模板替换将图片放置在卡片正面。以下示例展示了如何通过模板替换插入类:

CardTemplateOverride cardTemplateOverride =
    new CardTemplateOverride()
        .setCardRowTemplateInfos(
            Arrays.asList(
                new CardRowTemplateInfo()
                    .setTwoItems(
                        new CardRowTwoItems()
                            // The ids chosen here must be set on the object's TextModuleData and ImageModuleData
                            .setStartItem(
                                createTemplateItem("object.textModulesData['textId']"))
                            .setEndItem(
                                createTemplateItem("object.imageModulesData['imageId']")))));
GenericClass genericClass =
    new GenericClass()
        .setId(issuerId + ".classId")
        .setClassTemplateInfo(
            new ClassTemplateInfo().setCardTemplateOverride(cardTemplateOverride));

service.genericclass().insert(genericClass);


...


private static TemplateItem createTemplateItem(String fieldPath) {
  return new TemplateItem()
      .setFirstValue(
          new FieldSelector()
              .setFields(Arrays.asList(new FieldReference().setFieldPath(fieldPath))));
}

异常处理

如果 Wallet FeatureAPI 使用不当,可能会出现以下潜在错误:

短信 原因
映像不能同时具有 source_uri 和 private_image_id 发布者尝试在单个图片上设置 source_uri 和 private_image_id,这是不允许的
找不到发行方为 %s 的 ID 为 %s 的私有映像 在对象上设置不存在的私有映像 ID
无法将发行方 %s 的 ID 为 %s 的私有图片添加到对象 %s,因为该图片已用于对象 %s。私有映像只能与一个对象搭配使用。 尝试在多个对象上使用同一私有映像。如需将同一张私密图片用于多个对象,必须重新上传该图片,然后您会获得一个新的私密图片 ID,该 ID 可用于第二个对象