Posted by Wayne Piekarski, Developer Advocate, Android Wear
If you’re an Android Wear developer, we wanted to let you know of a change you might need to make to your app to improve the performance of your user’s devices. If your app is using BIND_LISTENER intent filters in your manifest, it is important that you are aware that this API has been deprecated on all Android versions. The new replacement API introduced in Google Play Services 8.2 is more efficient for Android devices, so developers are encouraged to migrate to this as soon as possible to ensure the best user experience. It is important that all Android Wear developers are aware of this change and update their apps as soon as possible.
Limitations of BIND_LISTENER API
When Android Wear introduced the WearableListenerService, it allowed you to listen to changes via the BIND_LISTENER intent filter in the AndroidManifest.xml. These changes included data item changes, message arrivals, capability changes, and peer connects/disconnects.
The WearableListenerService starts whenever any of these events occur, even if the app is only interested in one type. When a phone has a large number of apps using WearableListenerService and BIND_LISTENER, a watch appearing or disappearing can cause many services to start up. This applies memory pressure to the device, causing other activities and services to be shut down, and generates unnecessary work.
Fine-grained intent filter API
In Google Play Services 8.2, we introduced a new fine-grained intent filter mechanism that allows developers to specify exactly what events they are interested in. For example, if you have multiple listener services, use a path prefix to filter only those data items and messages meant for the service, with syntax like this:
<service android:name=".FirstExampleService"> <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="/FirstExample" /> </intent-filter> </service>
There are intent filters for DATA_CHANGED, MESSAGE_RECEIVED, CHANNEL_EVENT, and CAPABILITY_CHANGED. You can specify multiple elements, and if any of them match, it will call your service and filter out anything else. If you do not include a element, all events will be filtered out and your service will never be called, so make sure to include at least one. You should be aware that registering in an AndroidManifest.xml for CAPABILITY_CHANGED will cause your service to be called any time a device advertising this capability appears or disappears, so you should use this only if there is a compelling reason.
If you only need these events when an Activity or Service is running, then there is no need to register a listener in AndroidManifest.xml at all. Instead, you can use addListener() live listeners, which will only be active when the Activity or Service is running, and will not impact the device otherwise. This is particularly useful if you want to do live status updates for capabilities being available in an Activity, but with no further background impact. In general, you should try to use addListener(), and only use AndroidManifest.xml when you need to receive events all the time.
In general, you should only use a listener in AndroidManifest.xml for events that must launch your service. For example, if your watch app needs to send an interactive message or data to the phone.
You should try to limit the number of wake-ups of your service by using filters. If most of the events do not need to launch your app, then use a path and a filter that only matches the event you need. This is critical to limit the number of launches of your service.
If you have other cases where you do not need to launch a service, such as listening for status updates in an Activity, then register a live listener only for the duration it is needed.
There is more information available about Data Layer events and the use of WearableListenerService, and tags in the manifest. Android Studio has a guide with a summary of how to convert to the new API. The Android Wear samples also show best practices in the use of WearableListenerService, such as DataLayer and XYZTouristAttractions. The changes needed are very small, and can be seen in this git diff from one of the samples here.
Removal of BIND_LISTENER
With the release of Android Studio 2.1, lint rules have been added that flag the use of BIND_LISTENER as a fatal error, and developers will need to make a small change to the AndroidManifest.xml to declare accurate intent filters. If you are still using BIND_LISTENER, you will receive the following error:
AndroidManifest.xml:11: Error: The com.google.android.gms.wearable.BIND_LISTENER action is deprecated. [WearableBindListener] <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This will only impact developers who are recompiling their apps with Android Studio 2.1 and will not affect existing apps on user’s devices.
For developers who are using Google Play Services earlier than 8.2, the lint rules will not generate an error, but you should update to a newer version and implement more accurate intent filters as soon as possible.
In order to give users the best experience, we plan to disable BIND_LISTENER in the near future. It is therefore important that developers take action now, to avoid any future disruption experienced by users of their apps.