How I got Android notifications on an Apple Watch — a tale of many components
I love my Android. I love it a bit too much, that when I got an iPhone and Apple Watch for my startup so that we can develop more apps on them, I couldn’t make the switch. The Apple Watch was amazing, but I was too used to the openness of Android, that I was lacking power features on the iPhone.
Long story short, I loved the Apple Watch, but was sad that I couldn’t use it with my Android.
Sure, there are standalone apps out there, but receiving notifications was a feature I needed, so I set out on a mission to make that happen. And I did! After 3 days of trial and error, my Apple Watch now gets all notifications from my Pixel phone! Wanna know how, and try it for yourself? Read on!
Disclaimer: This is a tech-savvy tutorial, you need to know the basics of app development, have an Apple Developer Account and be able to build stuff on Xcode.
- Android: Android Studio, Firebase account
- Server: PHP server of your choice (I use DigitalOcean), Composer, Firebase PHP SDK, Simple DOM Parser (optional)
- Apple: Xcode, a Mac, Apple Developer account (paid)
Time to complete: 1 hour, if familiar with app and server development
The idea is simple: Since WatchOS 6.0, you can create standalone apps for the Apple Watch that do not need an iPhone to function.
- We’ll create an Android app that will have a Notification Listener Service, and for every notification, ping our PHP server with the notification title and body.
- We’ll create a little PHP script on our server that listens for calls from our Android app. It uses the package name of the notification’s sender, to grab an image from the Play Store of the app icon that sent the notification.
Then, using the Firebase SDK, it pushes a notification to a specific topic.
- We’ll create a standalone WatchOS app that as Firebase Messaging integrated, and is listening to the specific topic our server is sending messages to. The watch needs to be connected to WiFi/4G for this work.
Once the Android gets a notification, it calls the server, which in turn calls Firebase, which in turn calls our WatchOS app.
Step 1: Android app
Presuming you have experience creating apps for Android, it is going to be the most simple part of the tutorial. Create a basic activity, then create a NotificationListenerService service, as such.
Remember to replace the baseURL variable with the link to your .php file on your server, once you set that up.
Make sure to define your listener in your Android Manifest file, in the application tag, as such:
Finally, start the service from your MainActivity, as such:
- Don’t forget to add the Internet permission to your AndroidManifest.xml file
- Don’t forget to add Volley as a dependency to your app’s build.gradle file
- The notification access is a special permission that needs to be set by hand. You can do that via the intent call on the button I added in the MainActivity, or manually via the settings on your phone.
- The notification listener is a special type of service that is started and stopped by the system, depending on notification access. That is why the only way to stop your app from sending notifications is to disable notification access, or add extra configuration to the app that the service can read and act accordingly.
With this, you have completed the Android section of the tutorial. If all is well, build and run your app on your Android phone.
Step 2: Server side
Now, lets set up the PHP script that will receive notification calls from our Android app, and push notifications via Firebase to our Apple App.
Create a composer.json file, and add the Firebase PHP SDK dependency in it, then run the composer install command, to install the SDK in the vendor folder.
After we install the Firebase SDK, time to register a Firebase account. Once created (you don’t need Analytics enabled), click the gear icon next to Project Overview, then click Settings, and under Service Accounts click Generate new private key.
Download the JSON file, store it on your server in a folder that is NOT publicly accessible.
Finally, we create our watchNotification.php script in the same folder as our vendor folder. Read the comments carefully in the code, especially if you want to send the app’s icon via the notification, then you need to install the optional Simple DOM library and include it. Don’t forget to update the absolute path to your Firebase Service Account JSON file on line 57.
With that, we are done with 2 out of the 3 parts needed to make this work. Still with me? Come on, we’re almost there, just one part remaining!
Step 3: WatchOS app
Time for the last part. This has a bit more complex stuff, but nothing you can’t handle!
Copy example code
The amazing people at Google, have made an example app that does exactly what we need. We basically need to just copy over their code, from this git repo.
You’ll see that the Podfile in the example code has local dependencies. These are outdated, and we want the latest ones, so what we’ll do is edit the Podfile to look like this, making sure to set the correct target names:
Then just run pod install, and open the new .xcworkspace file that Pod has generated for us. From now on, use this file instead of the .xcodeproj file.
Register bundle IDs
Make sure to set your own bundle IDs for all targets that you copied over from Google, replacing the one they have com.google.firebase.extensions.dev with something of your own.
If Xcode didn’t automatically do this for you, make sure you register all bundle ids on your Apple Developer account page, and enable Push Notifications for them: https://developer.apple.com/account/resources/identifiers/list
Register your app in Firebase
Now, with bundle IDs in hand, go back to your Firebase account and add an iOS app. Important: Register the bundle that ends with .WatchKitApp in Firebase, not the base or or the extension one.
During registration, you will get a GoogleService-Info.plist file. Download this file, place it in the root folder of your project (where .xcworkspace is), and make sure the target membership is selected for all your targets.
Generate and set APN key
Firebase needs an Apple Push Notifications auth key to be able to reach your watch, so head over to your developer console, and generate an auth key, making sure to select Apple Push Notifications service (APNs) as the type.
Download the key, then head back to your Firebase project setting page from above, click Cloud Messaging, and under iOS app configuration, upload the APNs auth key.
Run the app
After all this, connect your iPhone and Apple Watch to Xcode, and run the app on your Watch. Follow the output in the console to make sure that Firebase can find the configuration file, connect to the service, generate a token, and subscribe to the “watch” topic. If all is well, your output will contain those things.
Try a test notification
On your Firebase console, from the list of links on the left, scroll down to Cloud Messaging and click Send your first message. Enter a title and body, in the next section select Topic as a target, and enter “watch” as the topic.
Finally, click Review and your window should look like this. You can ignore the red warning, that just means we didn’t enable Analytics for our project.
If you click publish, and all went well, your watch should receive a notification! Now, just make sure all parts are on, and your Android phone will start sending notifications to your Apple Watch!
Since this communication is done via the web, your watch needs to be connected. If you don’t have a 4G watch, then use an app like Automate, to automatically turn on a hotspot on your Android when you leave your home/work, so that your Apple Watch can connect to it and keep receiving notifications.
This was a crazy adventure to get our Android to talk with our Apple Watch, but it’s doable. Most of this can be simplified, and automated, but I doubt Apple will approve an official app that allows for this, so for the time being, it’s down to tinkering and hacking like this.
This can, of course, work backwards too, where the Apple Watch can talk to the Android phone via Firebase data messages (perhaps respond to a notification via the watch), but that is a project for another day.