BLE Ring: A One-Handed Bluetooth Remote for Claude Code
I had an idea the other day: what if I could control Claude Code on my phone with a Bluetooth ring?
I keep my Pixel 9 on a stand and I like to stay kicked back without reaching for the screen. I just want to talk to Claude, send the message, read the response, and repeat — all without getting up or leaning forward. The phone is right there on the stand. I just don’t want to touch it.
I looked online to see if anyone was doing this. I couldn’t find a single blog post, YouTube video, or forum thread about it. So I had a weekend, and I decided to see if I could actually pull it off.
Spoiler: I did. For $3.50.
And if you’ve tried something like this — or you’re thinking about it — I’d genuinely love to hear from you. What ring did you use? What worked, what didn’t? I’m not claiming to be the first person to do this. I’m just looking to connect with anyone else who’s explored this workflow. I want to learn your story and trade notes.
Why a Ring?
Some context on how I actually use Claude Code. On my desktop, I’ve already moved away from the keyboard for most interactions. I have macros mapped to my mouse — voice-to-text, up, down, enter — and I control the whole session through voice and a few button clicks. No typing. It works great.
Claude Code with remote control changed the game for me. You’re no longer stuck at your desk or laptop. You can control your entire computer from your phone, and with voice-to-text you don’t need a keyboard at all. So I thought: if I don’t need the keyboard on my desktop, why do I need to keep tapping the screen on my phone? I wanted to bring that same macro-button workflow to mobile. That’s where the ring came in.
The Problem
Claude Code on mobile is a great experience, but the interaction loop requires a lot of screen touching. Every single cycle looks like this:
- Tap the input field to bring up the keyboard
- Tap the mic to start voice dictation
- Speak your prompt
- Tap send
- Hide the keyboard to read the response
- Scroll through Claude’s output
That’s 4+ taps per cycle. If your phone is on a stand across the room and you’re comfortable on the couch, you’re constantly getting up to poke at the screen. It kills the flow.
I wanted to cut that down to as close to zero taps as possible.
The Ring — Yiser-J6
I didn’t want to overthink the hardware. I searched for the cheapest Bluetooth ring I could find and landed on the Yiser-J6 — $3.50. It’s marketed as a TikTok scroll ring. You put it on your finger, pair it over Bluetooth, and it lets you scroll through your feed without touching your phone.
It has 7 physical inputs: a circular D-pad (up, down, left, right), a center button, and two bottom buttons labeled “1” and “2.” Plenty to work with, right?
Not exactly.
The ring comes pre-loaded with touch and swipe actions on most of the buttons. A single short press on “up” fires a swipe gesture — not a keycode, but a raw touch event that Android treats like a finger moving across the screen. You can’t intercept that. You can’t remap it. It just scrolls. The two bottom buttons are even worse: “1” is the power button (hold to turn on/off), and “2” only fires touch events with no keycode at all.
Out of 7 buttons, only 3 ended up being usable for what I wanted. More on that in a minute.
Would I recommend this ring? No. If I were doing this again, I’d look for a BLE ring or controller that doesn’t have pre-loaded actions baked into the firmware. But for $3.50 to test whether the concept even works? It got the job done.
Step 1: Mapping the Claude App
Before even thinking about the ring, I needed to know exactly where to tap on the screen. Every action in the Claude Code app — the input field, the mic button, the send button, the hide-keyboard chevron — each one lives at a specific X/Y coordinate on the screen. If I could figure out those coordinates, I could program something to tap them for me.
Here’s how I did it:
First, I connected my Pixel 9 to wireless debugging. Android has a built-in wireless ADB feature — you enable it in Developer Settings, and it gives you a port to connect to. I used Tailscale so my desktop (running WSL2) and my phone are on the same private network, which made the wireless ADB connection dead simple.
Then — and this is the fun part — I used Claude itself on my desktop to map the phone. Claude connected to the Pixel over ADB, took screenshots of the Claude Code mobile app, dumped the UI tree with uiautomator, and figured out the exact coordinates for every tap target I needed:
- Input field — where to tap to bring up the keyboard
- Gboard mic button — where to tap to start voice dictation
- Send/Stop button — where to tap to send a message (same coordinate becomes “stop” while Claude is generating)
- Hide-keyboard chevron — Gboard’s down-arrow button that dismisses the keyboard
Using Claude to reverse-engineer the Claude app so I could build a remote for Claude. It’s meta, but it worked perfectly. At the end of this step, I had a list of coordinates. Each coordinate was an action. Now I needed triggers.
Step 2: Discovering What the Ring Can Actually Do
I paired the ring and started pressing buttons to see what signals it sends to Android.
Short presses — useless. Every short press fires a pre-loaded touch or swipe event. The ring’s firmware treats a quick press as “the user wants to scroll TikTok” and sends a raw finger-swipe to the screen. Android’s accessibility layer can’t intercept raw touch events from an input device — you’d need root access to grab the device node and filter the events at the kernel level.
Rooting was technically an option. With root, you could grab the ring’s input device node and filter out the unwanted touch events, giving you all 7 buttons as clean triggers. But rooting a Pixel requires unlocking the bootloader, which wipes the phone completely. It also trips Play Integrity, which breaks things like Google Pay and certain apps. That’s way too invasive for a $3.50 experiment. My phone isn’t rooted and I had no interest in going down that road.
I tried to find a way to switch the ring out of this mode. Maybe there’s a hidden key combination, a pairing mode, something in a companion app. Nothing. The firmware is what it is.
Long presses (~2 seconds) — this is where it got interesting. Holding a button down fires a real keycode — an actual key input that Android sees as a keyboard press. The long-press palette:
- UP → Volume Up
- DOWN → Volume Down
- LEFT → Previous Song
- RIGHT → Next Song
- CENTER → Play/Pause
These are standard media keycodes. Android can intercept them, and apps can remap them. Now we had something to work with.
But there was one more catch. I tested all five and found that UP and DOWN fire a swipe gesture before the keycode arrives. The ring starts the touch event immediately on press, and the keycode only comes about 1.3 seconds later. That initial swipe is baked into the firmware — it can’t be suppressed without root.
So CENTER, LEFT, and RIGHT were the only buttons that gave us clean keycodes with no unwanted side effects. Three buttons out of seven. A bummer, but three is better than zero.
Step 3: Key Mapper — Connecting Triggers to Actions
Now I had both halves of the puzzle:
- Triggers: 3 keycodes from the ring (Play/Pause, Previous Song, Next Song)
- Actions: 4 screen coordinates from the ADB mapping (input field, mic, send, hide keyboard)
Three triggers, four actions. One action would have to stay manual. More on that later.
To connect them, I used Key Mapper — an open-source Android app that intercepts keycodes and maps them to any action you want: screen taps, key presses, system actions, whatever. It doesn’t need root. It just needs accessibility permission, which you grant once.
I set up three maps:
- CENTER (Play/Pause) → Tap Gboard mic at
1036,1522— This starts and stops voice dictation. Gboard’s mic is a toggle: tap it once to start listening, tap it again to stop. So the same button handles both. - RIGHT (Next Song) → Tap Send/Stop at
959,1349— This sends the message when there’s text in the input field. When Claude is generating a response, the same coordinate becomes a “Stop” button. One button, two functions, depending on context. - LEFT (Previous Song) → Tap hide-keyboard chevron at
180,2360— This taps Gboard’s own down-arrow button to dismiss the keyboard, so you can read Claude’s response in full-screen mode.
One trigger, one action per button. No macros, no multi-step sequences. Keep it simple.
The Critical Discovery: show_ime_with_hard_keyboard
This almost killed the entire project.
When the ring pairs over Bluetooth, Android sees it as a hardware keyboard. And when Android detects a hardware keyboard, it hides the on-screen keyboard. No on-screen keyboard means no Gboard. No Gboard means no mic button. No mic button means the whole workflow falls apart.
I spent a while figuring out why the keyboard kept disappearing every time I connected the ring. The fix is one ADB command:
adb shell settings put secure show_ime_with_hard_keyboard 1
This tells Android: “Yes, there’s a hardware keyboard connected, but keep showing the soft keyboard anyway.” Set it once and it persists across reboots. If you’re trying to replicate this project and the keyboard keeps vanishing when you connect your ring, this is the fix.
The Floating Menu Nightmare
Here’s where I lost a few hours.
My original plan was more ambitious. Instead of three separate buttons, I wanted a single button that would do everything: tap the input field to focus it, wait a moment for the keyboard to animate up, then tap the mic to start dictation. One press, fully hands-free.
I built the macro in Key Mapper. It looked right. The coordinates were right. The timing was right. And every single time I pressed the button, instead of starting dictation, Gboard’s floating keyboard mode popped up — a small floating strip that took over the whole screen and broke everything.
The bizarre part: the exact same sequence of taps via ADB worked perfectly. adb shell input tap 540 2109, wait, adb shell input tap 1036 1522 — dictation started every time. But through Key Mapper, it always hit the floating menu.
I never fully figured out why. My best guess is that Key Mapper dispatches taps through Android’s accessibility service with a slightly longer press duration than ADB, and Gboard interprets that as a long-press on the toolbar, which opens the floating/one-handed keyboard menu.
The fix was simple: abandon multi-step macros entirely. One button, one tap, no sequences, no timing dependencies. Simpler won. The macro was clever in theory, but a single reliable tap beats a complex sequence that works 90% of the time.
The Working Loop
After all the debugging, here’s the actual usage flow:
- Tap the input field (manual — the one thing that’s not hands-free)
- MIDDLE — long-press the center button to start dictating
- Speak your prompt
- MIDDLE — long-press center again to stop the mic (critical: you must stop the mic before sending — if Gboard is still listening when you hit send, the floating menu pops up again. Not sure why, it doesn’t look like a layout shift, but something about the active mic state causes the send tap to trigger that menu instead. Close the mic first, then send works clean every time.)
- RIGHT — long-press right to send the message
- LEFT — long-press left to hide the keyboard and read Claude’s response in full screen
- Scroll with the ring’s native up/down (coarse fling) or your finger (fine scroll)
- Repeat from step 1
Once Key Mapper is configured, this runs completely standalone on the phone. No PC, no ADB connection, no tethering. The ring talks to the phone over Bluetooth, Key Mapper intercepts the keycodes, and the taps fire. Pick up the phone, walk to a different room, sit on the couch — it just works.
75% Hands-Free
The math is simple. The full interaction loop has 4 actions:
- Focus the input field
- Start/stop dictation
- Send
- Hide keyboard and read
We automated 3 out of 4. That’s 75% hands-free. Before the ring, every cycle was 4+ taps on the screen. Now it’s 1 tap (to focus the field) and 3 ring presses.
The missing 25% is frustrating because it’s solvable — in theory. A 4th button dedicated to “tap the input field” would close the loop to 100% hands-free. But the input field coordinate changes depending on whether the keyboard is up or down, so a fixed tap lands on different things in different states. And with only 3 usable buttons on this ring, there’s no spare to dedicate to it.
A better ring with more clean buttons would solve this. Or a smarter remapping approach — using Tasker with AutoInput to tap by accessibility label instead of coordinates, which would be immune to layout shifts. But for a $3.50 proof of concept, going from 4 taps to 1 is a win I’ll take.
What’s Next
The concept is proven. The limiting factor isn’t the approach — it’s this specific ring’s hardware. Here’s what I’d try next:
- A ring or controller with more buttons — even one extra clean button would close the hands-free gap. Some BLE remotes have 5-8 buttons without pre-loaded actions.
- A different keyboard app — an IME without a floating/one-handed mode would eliminate the entire class of bugs that killed the macro approach. If the floating menu can’t appear, the multi-step macro might just work.
- Tasker + AutoInput — tapping by accessibility label instead of screen coordinates. “Tap the element called ‘Send’” instead of “tap at 959,1349.” Immune to layout shifts, keyboard state changes, and screen rotation.
- A different BLE ring — there are other TikTok-style rings out there with more buttons and hopefully without pre-loaded actions. Same form factor, just better hardware. The Key Mapper setup transfers to any BLE device that emits keycodes.
The door is open. The workflow is proven. Now it’s just about finding better hardware.
Conclusion
For $3.50 and one afternoon, I built a working one-handed remote for Claude Code on my Pixel 9. The proof of concept works.
The entire setup is open source. Key Mapper is free. ADB is free. The ring is the cheapest thing on the internet that emits Bluetooth keycodes. No root, no jailbreak, no special apps beyond Key Mapper and Gboard.
Does the job feel finished? Honestly, no. I bought the cheapest ring possible to see if the concept was even viable, and it is — but there’s clearly more work to do. A better ring with more usable buttons, maybe a different key mapping app that handles macros more reliably, maybe a different approach to the field-focus problem. The proof of concept is done. The polishing is a project for another weekend.
But that’s the point. I went from 4 screen taps per interaction down to 1. The core loop works: dictate, send, read, repeat — all from across the room with my phone on a stand. And now I know exactly what to look for in the next ring.
If you want to try this yourself, start cheap like I did. Grab the cheapest BLE ring you can find, install Key Mapper, and see how far you can push it. Just pick a ring that doesn’t pre-load half its buttons with swipe actions. And don’t forget show_ime_with_hard_keyboard.