Skip to main content
← blog

27 October 2025

Building a Wear OS Shutter Remote for My Japan Trip

I'm heading to Japan and wanted a discreet way to trigger my Canon's shutter from my watch. So I built one.

flutterdartbluetoothandroidwearoscanon

I'm heading to Japan later this year. I've been planning the trip for a while, and one of the things I'm most looking forward to is the photography: temples, street scenes, the whole thing. The problem I kept thinking about: taking photos of myself in front of landmarks is awkward. Holding a phone at arm's length looks terrible. A tripod and a 10-second timer works but you're racing the shutter, and you can't see the frame until after.

What I actually wanted was a remote shutter release I could trigger from my wrist.

Canon's Bluetooth implementation

Canon added Bluetooth to most of their cameras a few years back, primarily for the Canon Camera Connect app, which handles photo transfer and basic remote control. What's less advertised is that the remote shutter functionality goes through Bluetooth LE (BLE), which means any device that can write to the right GATT characteristics can trigger the shutter. No proprietary SDK needed.

The pairing process does require mimicking the initial handshake that Canon Camera Connect performs. Canon doesn't publish this protocol. I relied on community reverse-engineering to identify the relevant GATT service and characteristics, then validated the handshake behavior by directly inspecting what the official app sends over BLE. The key pieces:

  • Pair with the camera over standard BLE
  • Write a specific byte sequence to a control characteristic to "authenticate" as a remote
  • From there, shutter release is a single GATT write: one byte to trigger, another to release

Why Flutter + Wear OS

I already had an Android watch (Wear OS), so the target platform was obvious. Flutter is my go-to for cross-platform mobile work, and the flutter_blue_plus package handles BLE on both Android handsets and Wear OS with the same API.

The watch app is intentionally minimal: one button, full screen, physical press triggers the shutter:

dart
Future<void> triggerShutter() async {
  await shutterCharacteristic.write([0x01], withoutResponse: true);
  await Future.delayed(const Duration(milliseconds: 100));
  await shutterCharacteristic.write([0x00], withoutResponse: true);
}

The withoutResponse: true flag is important for latency. BLE acknowledged writes add a round-trip that's noticeable on a shutter press.

The pairing flow

Wear OS's BLE permissions are stricter than phone-side Android in some ways (the watch needs explicit Bluetooth permissions declared in the manifest, and you have to handle the BLUETOOTH_SCAN / BLUETOOTH_CONNECT runtime permission request properly). Spent more time on that than on the actual protocol.

The camera shows up as a standard BLE peripheral. After the initial handshake, the connection is stable across short distances. I tested it reliably through about 8 metres with no obstacles. Should be plenty for a tripod shot.

What it looks like in practice

The Wear OS app shows a single large button. You set the camera on a tripod, frame the shot on the camera screen or tethered phone, step into frame, and press the button on your wrist. No running, no awkward phone angle, no visible remote in hand.

Phone app — scanning for cameras
Phone app — scanning for cameras
Watch app — one-tap shutter trigger on Wear OS
Watch app — one-tap shutter trigger on Wear OS

For Japan specifically, I'm planning to use it at places like Fushimi Inari early in the morning before the crowds arrive, the kind of shot where you want to be in the frame but also want the composition to be deliberate rather than a selfie grab.

What's next

The current version only handles shutter release. Canon's protocol also exposes focus control (half-press simulation) and some basic exposure settings. I might add a focus-then-shoot mode before the trip, useful for situations where the camera's autofocus might pick the wrong subject in a busy scene.

Source available on GitHub if your camera supports BLE and you want to try it.

// share

// comments