Http://developer.android.com/training/wearables/data-layer/events.html
The following are my notes when I study the official development documents, mainly translation, and in the middle will insert some of their own summary and research, hoping to help readers.
This article is divided into 2 parts:
Section1: How to get the results of data communication.
Section2: How to listen for data events in the data tier.
Where Section2 is divided into 2 modules:
1. Inheriting wearablelistenerservice;
2. Activity implements data interface.
Section 1:wait for the Status of data Layer calls-wait for the results of the operation
In the case of data communication, sometimes a Pendingresult object is returned, for example, the Putdataitem method is called. Once the Pendingresult object is built, Then the data operation is in the background queue. You can choose whether to process the result of the operation. The Pendingresult object allows you to get the results of the operation, either synchronously or asynchronously.
asynchronously waiting-asynchronous wait
If you are doing data manipulation in the UI thread, be careful about blocking the problem. Here you can use callback snooping to implement asynchronous waits:
Pendingresult.setresultcallback (new resultcallback<dataitemresult>() { @Override publicvoid onresult (final dataitemresult result) { if( Result.getstatus (). Issuccess ()) { "" + Result.getdataitem (). GetURI ());}} );
synchronously waiting-synchronous wait
If you perform data operations in a separate background service process, you can use synchronous waits to process the results of the operation and block the process until the results are obtained.
Dataitemresult result = Pendingresult. await (); if (Result.getstatus (). Issuccess ()) { "" + Result.getdataitem (). GetURI () );}
Section 2:listen for data layer events-Listen for the event
Because of the synchronization of data communication between the mobile phone and the watch, it is usually necessary to listen for some important events, such as data creation, message receiving, and communication connection.
Listen to data communication, can be implemented in the following two ways:
- Create a service that inherits from Wearablelistenerservice
- Create an activity that implements the Dataapi.datalistener data interface
1.With a WearablelistenerserviceUsage Scenarios
In general, a subclass service is built on both the mobile and the watch side. But if there is no need to listen for data events at any one end, there is no need to build them.
For example, you can build and pass data to your watch on your phone, and watch these data events to update your interface. But the watch side is only one-sided access to data, do not make any changes to the data, then the mobile phone side does not need to listen to data communication events.
Method Introduction
The next step is to introduce some important event methods for Wearablelistenerservice:
- Ondatachanged (): Increase, delete, change, these three kinds of events will call this interface. And both ends will be triggered by the call. → Bidirectional
- Onmessagereceived (): The message is sent from one end, and the interface at the other end is called. → Unidirectional
- Onpeerconnected (), onpeerdisconnected (): Triggers when both ends are connected or disconnected. Changing the connection state at one end invokes the interface at both ends. → Bidirectional
Implementation steps
- Inherit Wearablelistenerservice
- Listening for data communication events
- Declare in manifest and add intent filter to listen Com.google.android.gms.wearable.BIND_LISTENER this action
Code sample
Public classDatalayerlistenerservice extends Wearablelistenerservice {Private StaticFinal String TAG ="Datalayersample"; Private StaticFinal String Start_activity_path ="/start-activity"; Private StaticFinal String Data_item_received_path ="/data-item-received"; @Override Public voidondatachanged (Dataeventbuffer dataevents) {if(log.isloggable (tag, log.debug)) {log.d ( tag,"ondatachanged:"+dataevents); } Final List Events=freezableutils. freezeiterable (dataevents); Googleapiclient googleapiclient=NewGoogleapiclient.builder ( This). Addapi (WEARABLE.API). build (); Connectionresult Connectionresult=Googleapiclient.blockingconnect ( -, Timeunit.seconds); if(!connectionresult.issuccess ()) {LOG.E (TAG,"Failed to connect to googleapiclient."); return; } //Loop through the events and send a message//To the node, that created the data item. for(dataeventEvent: Events) {URI Uri=Event. Getdataitem (). GetURI (); //Get the node ID from the host value of the URIString nodeId =Uri.gethost (); //Set the data of the message to be the bytes of the URI. byte[] Payload =uri.tostring (). GetBytes (); //Send the RPCWearable.MessageApi.sendMessage (googleapiclient, NodeId, Data_item_received_path, Paylo AD); } }}
Annotations:
Final List events = freezableutils. freezeiterable (dataevents);
The function here is to convert the data object dataevents to a non-modifiable type through the tool class freezableutils, to avoid data changes during the process of processing the data.
Connectionresult Connectionresult = Googleapiclient.blockingconnect (timeunit.seconds);
Blocks the current thread, acquires a connection state within 30 seconds, or is considered a timed-out connection. Because OnDataChange is part of an asynchronous thread, this does not cause the main thread to block. Note that here is the connection to get and googleapiclient, while section one is the result of sending the data.
Manifest statement
<service android:name=". Datalayerlistenerservice"> <intent-filter> <action android:name=" Com.google.android.gms.wearable.BIND_LISTENER " /> </intent-filter></service>
Permissions within Data Layer callbacks
Watch out.
Permission issues in the data callback interface
To callback the data event interface, Google play binds your service and calls through the IPC. This also causes your callback interface to inherit the permissions of the calling process.
If you want to do some privileged operations in the callback interface, you will find that the security validation fails, and you will find that the process ID printed in the callback interface is the ID of the process that triggered the callback interface, not the process of your application.
To solve this problem, first call clearcallingidentity () to reset the ID, revert to the application process ID, perform the action you need, and then call back to the ID of the restorecallingidentity () caller.
long token = binder.clearcallingidentity (); Try { finally { binder.restorecallingidentity (token);}
in-depth study of Wearablelistenerservice:
The following life cycle test environments are on the emulator and may be slightly different in other environments.
- Life cycle: Completely controlled by Android Wear!
- The premise: In the manifest of the declaration, monitoring Com.google.android.gms.wearable.BIND_LISTENER This action
- Phenomenon: When the watch and phone are disconnected, the demo,service is not called OnCreate method. The OnCreate method is called immediately when the connection is made.
- Life cycle Processes:
Connecting Mobile: onCreate > onpeerconnected
Operation Process: If the service does not receive the message, the last time the callback is quasi, about 8-12 seconds after the suicide, call OnDestroy.
Disconnect the phone: If the service is dead: onCreate > Onpeerdisconnected > OnDestroy (wait 8-12 seconds), if the service is active, the next 2 methods are called.
- It has already implemented the 3 interfaces of Dataapi.datalistener,messageapi.messagelistener,nodeapi.nodelistener.
Summarize:
12. Short life cycle, stop operation 8~34. A state change occurs in the background of the connection, it is created immediately, the callback interface is called, To handle the application business
2.With a Listener Activity method introduction
If your application just needs to listen for data communication events while the user is open, without having to listen for data changes in the background, you can implement the following interfaces to achieve your needs.
- Dataapi.datalistener
- Messageapi.messagelistener
- Nodeapi.nodelistener
Implementation steps
The next step is to create an activity that listens for data communication events
- Implementing interfaces: Implementing the interfaces enumerated above (depending on the requirements, not all implementations)
- Create a Service object: Create a Googleapiclient object in the OnCreate method that implements the connection to the data communication.
- Connection service: Call Googleapiclient's Connect method in the OnStart method to connect to the service
- Register listener: When Googleapiclient is connected to the service, it will callback the Onconnected method, then we can register the listener here to listen to the communication events we are concerned about.
- Unregister the Listener and disconnect the service: In the OnStop method, unregister the listener before you register, and then disconnect the Googleapiclient service.
- Implement the event callback interface: Implement interfaces based on registered listeners and handle related requirements.
Code sample
Here is a sample that implements the Dataapi.datalistener:
Public classMainactivity extends Activity implements Dataapi.datalistener, Connectioncallbacks, Onconnectionfailedlistener {@Overrideprotected voidonCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.main); Mgoogleapiclient=NewGoogleapiclient.builder ( This). Addapi (WEARABLE.API). Addconnectioncallbacks ( This). Addonconnectionfailedlistener ( This). build (); } @Overrideprotected voidOnStart () {Super.onstart (); if(!mresolvingerror) {Mgoogleapiclient.connect (); }} @Override Public voidonconnected (Bundle connectionhint) {if(log.isloggable (tag, log.debug)) {log.d ( tag,"Connected to Google Api Service"); } Wearable.DataApi.addListener (Mgoogleapiclient, This); } @Overrideprotected voidOnStop () {if(NULL! = Mgoogleapiclient &&mgoogleapiclient.isconnected ()) {Wearable.DataApi.removeListener (mgoogleapiclient, This); Mgoogleapiclient.disconnect (); } super.onstop (); } @Override Public voidondatachanged (Dataeventbuffer dataevents) { for(dataeventEvent: dataevents) { if(Event. GetType () = =dataevent.type_deleted) {LOG.D (TAG,"DataItem deleted:"+Event. Getdataitem (). GetURI ()); } Else if(Event. GetType () = =dataevent.type_changed) {LOG.D (TAG,"DataItem changed:"+Event. Getdataitem (). GetURI ()); } } }
Android Wear development-Data Communication-section III: Event handling