文档

库

表盘和数据字段

表盘无法响应按键,也无法在前台联网。因此库会在后台向我们的服务器检查,你的表盘在你选择的位置绘制 QR 码,而 Garmin 的登录通知让买家无需扫码即可付款。数据字段同理。

工作原理

  • 后台询问。表盘的后台服务在服务器指定的时间,向我们的服务器发送与应用相同的请求。
  • 时间始终在最上层。对表盘来说,看时间是主要功能,Garmin 建议不要用付费墙挡住它。锁定时,表盘在你选择的位置绘制 QR 码。数据字段则在自己的区域内绘制。
  • 链接在设置中。表盘还会把购买链接写入其设置,手机上的 Connect IQ 应用会显示它。买家可以直接在那里打开,无需扫码。
  • 通知省去扫码。表盘锁定且手机已连接时,它会发送 Garmin 的登录通知。买家点开、付款,表盘几秒内即可解锁。

添加到表盘或数据字段

表盘和数据字段只使用 lib/watch/face:PayFace.mc 和 PayFaceScope.mc。

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/face
manifest.xml
<iq:permissions>
    <iq:uses-permission id="Background"/>
    <iq:uses-permission id="Communications"/>
</iq:permissions>

配置文件标注为 (:background),因为后台会读取它。请在其中保留 TRIAL_DAYS,不设试用时设为 0:表盘部分会直接读取它。

source/PaywallConfig.mc
// PaywallConfig.mc: from your dashboard (Trail Face). Public, not a secret.
import Toybox.Lang;

(:background)
module PaywallConfig {
    const URL = "https://pay.example/api/K7Q2/c";   // your app's address
    const TRIAL_DAYS = 7;
}

钩子

位置调用
getInitialView()每次启动时调用 Paywall.startTrial(); Paywall.schedule(false);
getServiceDelegate()return [new PayBg()];
onBackgroundData(data)Paywall.take(data);
onSettingsChanged()Paywall.soon();
onUpdate(dc)if (!Paywall.unlocked()) { Paywall.drawQr(dc, x, y, side); }

一个完整的表盘,锁定时时间在上、QR 码在下:

source/PayFaceApp.mc
import Toybox.Application;
import Toybox.Background;
import Toybox.Graphics;
import Toybox.Lang;
import Toybox.System;
import Toybox.Time;
import Toybox.WatchUi;

// A small face for measuring: the time, and the QR code under it while locked.
(:background)
class PayFaceApp extends Application.AppBase {
    function initialize() {
        AppBase.initialize();
    }

    function onStart(state as Dictionary or Null) as Void {
    }

    function getInitialView() {
        Paywall.startTrial();
        Paywall.schedule(false);
        return [new PayFaceView()];
    }

    function getServiceDelegate() {
        return [new PayBg()];
    }

    function onBackgroundData(data) as Void {
        Paywall.take(data);
    }

    // Saving the face's settings on the phone (the buy page suggests it after paying): ask now
    // (5 minutes after the last check at the soonest, Garmin's rule).
    function onSettingsChanged() as Void {
        Paywall.soon();
    }
}

class PayFaceView extends WatchUi.WatchFace {
    function initialize() {
        WatchFace.initialize();
    }

    function onUpdate(dc as Graphics.Dc) as Void {
        var w = dc.getWidth();
        var h = dc.getHeight();
        var t = System.getClockTime();
        dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
        dc.clear();
        dc.drawText(w / 2, h * 30 / 100, Graphics.FONT_NUMBER_MEDIUM, t.hour.format("%02d") + ":" + t.min.format("%02d"),
            Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER);
        if (!Paywall.unlocked()) {
            Paywall.drawQr(dc, w / 2, h * 68 / 100, w * 36 / 100);
        }
    }
}

添加一个只读的 unlock 属性。表盘会用服务器应答中的购买链接填入它。在你自己的资源中定义 UnlockTitle 字符串。

resources/settings/settings.xml
<resources>
    <!-- The buy link, written by the face from the server's answer: the phone's Connect IQ app
         shows it in this face's settings, so a buyer can open it without scanning. -->
    <properties>
        <property id="unlock" type="string"></property>
    </properties>
    <settings>
        <setting propertyKey="@Properties.unlock" title="@Strings.UnlockTitle">
            <settingConfig type="alphaNumeric" readonly="true"/>
        </setting>
    </settings>
</resources>

绘制 QR 码

  • Paywall.drawQr(dc, x, y, side) 在白色方块上绘制宽 side 的 QR 码,中心位于 x, y。收到第一次应答前不绘制任何内容。
  • 只在 !Paywall.unlocked() 时调用。
  • 只在屏幕完全点亮时绘制,切勿在 AMOLED 手表的常亮模式下绘制。

Garmin 的登录通知

  • 发送时机:检查首次发现表盘处于锁定状态时(试用结束或没有试用)发送一次。表盘锁定期间,买家每次保存表盘设置时会再次发送。仅在手机已连接时发送:它需要手机本身,而不是 Wi-Fi。
  • 买家看到的:手机上 Garmin 自己的通知。文字由 Garmin 撰写(“<app> needs you to sign in”),任何应用都无法更改。点按后会在 Garmin Connect 自带的浏览器中打开你的结账页面。
  • 付款之后:页面结束,手机把结果交给手表,表盘的后台向我们的服务器询问。仅凭结果不会解锁任何东西,因为任何人都能输入它的地址。只有我们服务器的应答才能解锁。
  • 绝不会误发两次:后台会自行标记为已发送(CIQ 3.2 及更高版本),即使表盘之后没有马上运行。在无法发送的手表上,QR 码和设置链接仍然有效。

应用不发送它。应用的购买界面在付款约一秒后就已解锁。

解锁需要多久

我们的服务器无法主动联系手表。表盘只有在下次检查时才知道付款,而 Garmin 最多每 5 分钟允许一次后台检查。

买家的付款方式表盘解锁
点按了登录通知几秒内
在安装或试用结束后的 2 天内扫码或使用了设置链接10 分钟内
同上,但稍晚一小时内
付款后在手机上保存了表盘设置在 Garmin 允许的最早一次检查时:距上次至少 5 分钟
  • 一旦检查发现结账页面已打开,表盘会在半小时内每 5 分钟检查一次。
  • 试用期间,表盘在试用结束时检查;如果每日检查更早,则每天检查。
  • 检查失败(没有手机)后,下一次在一小时后。

注解与作用域

概览和后台代码只能访问为其加了注解的代码。保留库自带的注解,并让你自己的注解与之匹配。

  • 表盘和数据字段:PaywallConfig 标注为 (:background),你的 AppBase 类也一样(如示例所示):它的 getServiceDelegate() 在后台运行。PayBg 和 PayFaceScope.mc 已加好注解。
  • 带概览的应用:glance/PayScope.mc 和 PaywallConfig 标注为 (:glance)。概览只能调用 Paywall.active()、Paywall.unlocked() 和 Paywall.trialLeft(),不能调用其他内容。
  • 自带后台服务的应用:glance-bg/PayScope.mc、注解为 (:glance, :background) 的 PaywallConfig,以及 Background 权限。
  • 仅限应用:Pay.mc 中的所有内容,包括 Paywall.open()、购买界面及其字符串。切勿在概览或后台代码中调用。
Esc