So I finally got it to work. It took a combination of things that needed to be set up, but I'll list them all.
- The Gradle. You need to make sure the mobile version and the wearable version has the same application id, the same version code, the same version name, and possibly the same play-services version. This is easier to handle if you use the project gradle file to hold these values and have each module reference these values.
In the Root build.gradle file have:
ext {
TARGET_SDK_VERSION = 25
VERSION_CODE = 7
VERSION_NAME = '2.0'
COMPILE_SDK_VERSION = 25
BUILD_TOOLS_VERSION = '25.0.2'
APPLICATION_ID = "com.example.projectname"
PLAY_SERVICES_WEARABLE = 'com.google.android.gms:play-services-wearable:9.4.0'
}
In each of the module build.gradle files, these can be referenced as shown below:
apply plugin: 'com.android.application'
android {
compileSdkVersion rootProject.ext.COMPILE_SDK_VERSION
buildToolsVersion rootProject.ext.BUILD_TOOLS_VERSION
defaultConfig {
applicationId rootProject.ext.APPLICATION_ID
minSdkVersion 20
targetSdkVersion rootProject.ext.TARGET_SDK_VERSION
versionCode rootProject.ext.VERSION_CODE
versionName rootProject.ext.VERSION_NAME
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
provided 'com.google.android.wearable:wearable:2.0.1'
compile 'com.google.android.support:wearable:2.0.1'
compile rootProject.ext.PLAY_SERVICES_WEARABLE
}
- The Manifest. With the new updates to the play services, a
WearableListenerService
must now have an intent-filter
defined for each overrided function to be called by the android system. In the case of the onCapabilityChanged
function, the intent filter should be defined as:
<service
android:name=".MyWearableListenerService"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.CAPABILITY_CHANGED" />
<data android:scheme="wear" android:host="*"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data android:scheme="wear" android:host="*" android:pathPrefix="/PREF"/>
<data android:scheme="wear" android:host="*" android:pathPrefix="/start"/>
</intent-filter>
</service>
The intent-filter
for onCapabilityChanged
is com.google.android.gms.wearable.CAPABILITY_CHANGED
. Along with that, the intent-filter also needs to be told the data scheme and host. This can simply be data android:scheme="wear" android:host="*"
. The pathPrefix
can be omitted for this intent-filter. Notice that the intent-filter for the com.google.android.gms.wearable.DATA_CHANGED
and com.google.android.gms.wearable.MESSAGE_RECEIVED
needs the pathPrefix
defined to be able to have their respective functions called in the service.
- The capability file. In order for the
onCapabilityChanged
function to launch, the system needs to detect a device with a capability being connected. To do this, we must have the capability defined in an xml file in each module.
To do this, in each module, save a file named wear.xml
in the res/values directory. The file must have a string array named android_wear_capabilities
with items that describe the capabilities you wish your module to advertise to another device. Below is an example of a wear.xml
file included in a wearable module.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="android_wear_capabilities">
<item>verify_remote_wear_app</item>
</string-array>
</resources>
First, It is important to note that the file must be named wear.xml
and must be placed in the values directory. Secondly, the string-array must be named android_wear_capabilities
. Also make sure that every capability in each module has a unique name.
If any of the above is not correct, then the onCapabilityChanged
function will never be called, and you will be pulling your hair out in frustration.
Now, to actually tell if a device was disconnected, use the onCapabilityChanged
function:
public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
super.onCapabilityChanged(capabilityInfo);
if(capabilityInfo.getNodes().size() > 0){
Log.d(TAG, "Device Connected");
}else{
Log.d(TAG, "No Devices");
}
}
This function will tell you when a device has connected or disconnected, assuming only 1 device is connected at a time.