B4A Library Wearable DataLayer

What is it?
Not so recently a new branch of the Android platform was released for wearables (Watches and things) know simply as Android Wear. Wearables running Android Wear are made to be an extension for your existing mobile Android device. They bring notifications and app information / interaction out of your pocket and onto your wrist (and maybe other places if other wearable devices are released). I believe notifications will account for about 80% of the usage of these wearable devices. Wearable notification support has been possible for a while with the Notification Builder library, and the possibility to make apps that run on Android Wear has also been possible Tutorial. There was still a little issue; your mobile device and your wearable device couldn't talk to each other.

So, here is the Wearable DataLayer library. It allows you to communicate between the 2 devices. There are a couple of ways this works. There are:
  • Messages - these are 'send and forget' one way messages for small amounts of information (<100 KB)
  • DataMaps (Google call them DataItems, externally, but DataMaps internally o_O) - These are maps of data that are kept in sync on the Wear Network (a virtual connection between the devices). This data can be changed from either side and the data will sync to all other devices. DataMaps can hold Strings, Ints, Booleans, etc.
  • Assets - These are technically part of DataMaps but it is easier to explain them separately and you create them like so. Assets are basically used to transfer larger (anything > 100 KB) blocks of information as a File or Bitmaps. Assets are added to DataMaps and the system takes care of the transfer over bluetooth and caching, avoiding re-transmission.
This library has literally taken me an lifetime to make and I can only apologize for that, I hoped it would have been waaaaaay before now but sometimes life gets in the way of hobbies.

How To Install

First of all, copy the .jar and .xml to your additional libraries folder like any other library.

The use of this library requires the inclusion of Google Play Services. Similar to the Android-Support libraries, you have to download this with sdk manager and copy the library file(s) over to your additional libraries folder. A typical place for this would be

C:\Program Files\Android\sdk\extras\google\google_play_services\libproject\google-play-services_lib\libs

Although this path may be different depending on your installation.

It also requires 'AdditionalRes'. Again the path may vary. This is just for the Version ID of Play Services.
#AdditionalRes: C:\Program Files\Android\sdk\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms

I will update that post a little in the future and also create / post a few simple examples to help you all out.

Note: I have edited a few bits since my last BIG testing session, hopefully it won't have broken anything. I've run a few tests but thought it was about time I got this online so I will fix any issues as they come up. Also, a lot has changed since the BETA so the examples for that won't work, though the principles are the same so you should be able to get the idea from it.

Documentation

WearableDataLayer
Author:
BarxDroid
Version: 1

  • Methods:
    • AddDynamicListener
      Adds a dynamic listener to receive message events.
      A dynamic listener is create at runtime and will be removed once the process is stopped or once RemoveListener is called.
    • Info
      NOTE: This method doesn't do anything and is to provide information only.
      A Message is used to 'Send and forget' small amounts (<100KB) of data.
      You can receive the messages either with dynamic or static receivers.
      Dynamic - Will only be received while the listener is registered.
      Register with .AddDynamicReceiver.
      You must also unregister once done using .RemoveDynamicReceiver
      static - More complex but means you can receive messages at any time
      Add the following text to the Manifest Editor
      <code>AddApplicationText(
      <service android:name="barxdroid.wearabledatalayer.ListenerService"
      android:label="Wearable Listener">
      <intent-filter>
      <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
      </intent-filter>
      </service>)
      </code>
      Then add a service called 'WearListenerService to your project and in the service module, use code like this.
      <code>
      Sub Process_Globals
      Dim WL As WearableListener
      End Sub
      Sub Service_Start (StartingIntent As Intent)
      WL.Initialize("WL")
      WL.HandleIntent(StartingIntent)
      End Sub
      Sub WL_MessageReceived(SourceNodeID As String, RequestID As Int, msgPath As String, Data As String)
      ToastMessageShow(Data, False)
      End Sub
      </code>
    • IsInitialized As Boolean
    • RemoveListener
      Removes the dynamic listener so no more messages will be received
    • Send (NodeID As String, Timeout As Long, msgPath As String, Data As String)
      Sends a message to a specified node
      NodeID - The ID of the node to connect to.
      Timeout - The timeout before the message sending will fail in milliseconds.
      Path - Denotes a path identifier to specify a particular endpoint at the receiving node.
      Data - A ByteArray of data to pass. Do not pass >100KB. Pass Null if not required.
  • WearableAsset
    Methods:
    • CreateFromBitmap (bitmap As Bitmap) As Asset
      Creates an Asset to use from a Bitmap
    • CreateFromFile (Dir As String, Filename As String) As Asset
      Creates an Asset to use from a File
    • Info
      This method doesn't do anything, it is here purely for informational purposes.
      An asset is used to send a binary blob of data such as an image.
      You attach an asset to a DataItem.
      The system takes care of conserving bluetooth by caching large assets to avoid re-transmission.
  • WearableDataLayer
    Events:
    • BitmapResult (Tag As String, Result As Bitmap)
    • Connected ( As )
    • ConnectionFailed (ErrorCode As Int, Reason As String)
    • ConnectionSuspended (Reason As String)
    • DataChanged (ChangedItems As Map, DeletedItems As Map)
    • DataMapAdded (Success As Boolean)
    • DataMapDeleted (Path as string As , Success As Boolean)
    • DataMapResults (Success As Boolean, Results As Map)
    • FileResult (Tag As String, Dir As String, Filename As String, Success As Boolean)
    • LocalNodeIDResult (Success As Boolean, NodeID As String, NodeDisplayName As String)
    • MessageReceived (SourceNodeID As String, RequestID As Int, msgPath As String, Data As String)
    • MessageSent (Success As Boolean)
    • NodeResults (Results As List)
    • PeerConnected (ID As Int, DisplayName As String)
    Fields:
    • message As Message
    Methods:
    • AddDataMap (Path As String, dataMap As DataMap)
      Adds a Data Map to the Client to sync across the Wearable Data connection.
      DataMaps are synchronized across all devices
      Path - The path to store the DataMap under. e.g "/User"
      DataMap - The DataMap object to add
      Will call DatamapAdded() once complete returning the path for Identification and the success
      Also triggers DataChanged() event if new information is added
    • ClearCallingIdentity
    • Connect
      Connects the Google Play services client (required for the Data Layer to work)
      The _onConnected event will raise once the connection is successful.
      Do NOT attempt to use the Data Layer until the connection is successful
      Make sure you disconnect the client once done (probably best to do this in Activity_Pause()
    • DeleteDataMap (Path As String)
      Deletes a DataMap
      Path - The path which the DataMap resides.
      Calls DataMapDeleted() Event if present, with the success of the action
    • Disconnect
      Disconnects the Google Play services client
      Should always be called once you have finished with the Data Layer e.g. when the app closes or is paused.
    • GetAllDataMaps
      Returns all the present DataMaps as a Map.
      Each Map Key-Value pair is as follows
      Key - The path that the DataMap resides
      Value - The DataMap object

      The results will be returned in the DataLayer_DataMapResults() event
    • GetBitmapFromAsset (tag As String, asset As Asset)
      Gets a Bitmap from an Asset
      Tag - a Tag used to identify the request in the resulting callback
      Asset - the Asset object to extract the File from
      Result returned in BitmapResult() callback
    • GetConnectedNodes
      Get a list of the connected Nodes (Devices)
      The returned List will contains a Map for each node.
      The map will then contains 3 Key-Value pairs:
      ID - The ID of the node, this is used to reference the node when sending messages etc
      DisplayName - A HumanReadable name for the device (on my Samsung Gear Live this matched the ID so was of no use)
      ToString - A string representation of the full Node object, used mainly for my testing

      Result returned in NodeResults() Event
    • GetDataMap (Path As String, Tag As String)
      Gets an existing DataMap
      Path - the path that the DataMap resides
      Tag - a tag that is passed through to the results to make the result set identifiable
      If there is more than one DataMap with the same Path present on the Wear network. e.g. from different Nodes.
      All the DataMaps with that name will be returned.
      Use GetDataMap2 to specify a Node to narrow down a specific DataMap.
      Results are returned in DatamapResults() Event
    • GetDataMap2 (NodeID As String, Path As String, Tag As String)
      Similar to GetDataMap but allows you to specify a NodeID.
    • GetFileFromAsset (tag As String, asset As Asset, TargetDir As String, TargetFilename As String)
      Gets a File from an Asset
      Tag - A tag used to identify the request in the resulting callback
      Asset - The Asset object to extract the File from.
      TargetDir - The directory where the File will be created
      TargetFilename - The filename that the extracted File will be named
      Result returned in FileResult() callback
    • Initialize (Eventname As String)
      Initializes the object.
      Note: this library requires Android 4.3 (API18) or above
    • LocalNodeID
      Gets the NodeID of the local Device
      Result returned in LocalNodeIDResult() event
    • RestoreCallingIdentity
  • WearableDataMap
    Methods:
    • Clear
      Clears all previously added data items from the DataMap
    • ContainsKey (Key As String) As Boolean
      Checks if the given key is contained in the DataMap.
      Returns True if the key is present
    • Get (Key As String) As Object
      Returns the DataMap entry with the given Key as an Object
    • GetAsset (Key As String) As Asset
      Gets an Asset data item from the DataMap
      Key - The reference as set in in the PutAsset() method
    • GetBoolean (Key As String) As Boolean
      Gets a Boolean data item from the DataMap
      Key - The reference as set in in the PutBoolean() method
    • GetByte (Key As String) As Byte
      Gets a Byte data item from the DataMap
      Key - The reference as set in in the PutByte() method
    • GetByteArray (Key As String) As Byte[]
      Gets a Byte Array data item from the DataMap
      Key - The reference as set in in the PutByteArray() method
    • GetDouble (Key As String) As Double
      Gets a Double data item from the DataMap
      Key - The reference as set in in the PutDouble() method
    • GetFloat (Key As String) As Float
      Gets a Float data item from the DataMap
      Key - The reference as set in in the PutFloat() method
    • GetFloatArray (Key As String) As Float[]
      Gets a Float Array data item from the DataMap
      Key - The reference as set in in the PutFloatArray() method
    • GetInt (Key As String) As Int
      Gets an Int data item from the DataMap
      Key - The reference as set in in the PutInt() method
    • GetLong (Key As String) As Long
      Gets a Long data item from the DataMap
      Key - The reference as set in in the PutLong() method
    • GetLongArray (Key As String) As Long[]
      Gets a Long Array data item from the DataMap
      Key - The reference as set in in the PutLongArray() method
    • GetString (Key As String) As String
      Gets a String data item from the DataMap
      Key - The reference as set in in the PutString() method
    • GetStringArray (Key As String) As String[]
      Gets a StringArray data item from the DataMap
      Key - The reference as set in in the PutStringArray method
    • Initialize
      Initializes the object.
      No Eventname is required. The DataLayer Eventname is used.
    • IsInitialized As Boolean
    • PutAsset (Key As String, Asset As Asset)
      Adds an Asset data item to the DataMap
      Key - a key used to reference the data item
      Asset - the Asset object to pass.
    • PutBoolean (Key As String, Val As Boolean)
      Adds a Boolean data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutByte (Key As String, Val As Byte)
      Adds a Byte data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutByteArray (Key As String, Val() As Byte)
      Adds a Byte Array data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutDouble (Key As String, Val As Double)
      Adds a Double data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutFloat (Key As String, Val As Float)
      Adds a Float data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutFloatArray (Key As String, Val() As Float)
      Adds a Float Array data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutInt (Key As String, Val As Int)
      Adds an Int data item to the DataMap.
      Key - a key use to reference the data item
      Val - the value to set to.
    • PutLong (Key As String, Val As Long)
      Adds a Long data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutLongArray (Key As String, Val() As Long)
      Adds a Long Array data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutString (Key As String, Val As String)
      Adds a String data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • PutStringArray (Key As String, Val() As String)
      Adds a String Array data item to the DataMap
      Key - a key used to reference the data item
      Val - the value to set to.
    • Remove (Key As String)
      Removes an item from the DataMap with the given Key
    • Size As Int
      Returns the number of Key-Value pairs currently in the DataMap
    • isEmpty As Boolean
      Return True if the DataMap is currently empty
    • toByteArray As Byte[]
      Returns the DataMap as a ByteArray
    • toString As String
      Returns a string representation of the DataMap
  • WearableListener
    Events:
    • DataChanged (ChangedItems As Map, DeletedItems As Map)
    • MessageReceived (SourceNodeID As String, RequestID As Int, msgPath As String, Data As String)
    Methods:
    • HandleIntent (StartingIntent As IntentWrapper) As Boolean
      Used to handle the starting intent when using static listeners.
      Will call the following events:
      _MessageReceived - When a message is received
      _DataChanged - When a DataMap is changed on the Wear Network
    • Initialize (EventName As String)
      initilizes the object and set the EventName for callback events

To Be Continued.............
 

Attachments

  • WearableDataLayer.zip
    30.8 KB · Views: 612

canalrun

Well-Known Member
Licensed User
Longtime User
*** Another Example App ***

Hello,
I made an example app, based on warwound's Fused Location Provider library and example:
https://www.b4x.com/android/forum/threads/fusedlocationprovider.50614/

*** I should add that you need to install the fusedlocationprovider library as described in the link above ***

upload_2015-6-1_17-43-55.png



This example is for an Android Wear watch. it includes a project for the watch, but requires no companion project for the mobile device.

I used B4A version 4.3.

The Set Start button saves your Last Location internally and shows the distance to your current Location on the fourth line of the middle label.

If your Android Wear watch includes a GPS it should make use of that to show your location. You should be able to walk around with your watch and have the distance from Start change.

My watch does not include a GPS. It gets the location information via the Bluetooth connection to the phone. Theoretically if I walked around carrying the watch and phone the distance to Start would change, although I haven't tried this.

To install this app:
  • Connect the watch to ADB via USB connection. Around post #29 of this thread there are instructions for connecting to ADB via USB.
  • Compile the project using B4A (v 4.3)
  • it will be downloaded to the watch via USB. (on my device it takes about 90 seconds, be patient, and don't quit when the "taking too long" dialog pops up)
  • The app shows up on the watch with the title FusedLocationProvider.

Barry.
 

Attachments

  • FLP.zip
    13.6 KB · Views: 257
Last edited:

potman100

Active Member
Licensed User
Longtime User
Was wondering if you created an app like above, only on the watch, would it be possible to manipulate the services on
the phone, I was thinking of say turning wifi off on the phone from the watch ?

Or would you need to use the client server model of the DataLayer, that Barx has so kindly provided ?
 

canalrun

Well-Known Member
Licensed User
Longtime User
I would imagine you would need some kind of client-server model sending messages from the watch to the mobile.
 

barx

Well-Known Member
Licensed User
Longtime User
Was wondering if you created an app like above, only on the watch, would it be possible to manipulate the services on
the phone, I was thinking of say turning wifi off on the phone from the watch ?

Or would you need to use the client server model of the DataLayer, that Barx has so kindly provided ?

As far as I'm aware, there isn't any way for direct manipulation like that. You would have to do Wear device <-> Phone <-> system services / settings
 

nibbo

Active Member
Licensed User
Longtime User
I am guessing this won't work with the Gear Fit?
If not, will it work with any android smart watch?
 

barx

Well-Known Member
Licensed User
Longtime User
I am guessing this won't work with the Gear Fit?
If not, will it work with any android smart watch?

It only works with Android Wear devices which I believe the Gear Fit just misses out on. The Gear Live is currently the only Samsung smart watch supported. Then there are other manufacturers like the LG G Watch / G Watch R / Urbane. Moto 360. Asus Zen Watch, I think the Sony Smartwatch 3
 

maleche

Active Member
Licensed User
Longtime User
I would like to develop and wearable app with buttons that sends bluetooth data by simply touching a button on the screen. will this be possible?
thanks!
 

canalrun

Well-Known Member
Licensed User
Longtime User
*** Another Example App ***

Hello,
I have attached another example app with source. This app uses a Data Map to send a File Asset from a Mobile (phone) to connected wearable device nodes (watches). The wearable device then sends a message back to the Mobile indicating success or failure.

upload_2015-7-3_23-43-14.png


upload_2015-7-3_23-43-42.png


  • I compiled this app using B4A version 4.30
  • It uses several third-party and Anywhere Software libraries, including: byteconverter, javaobject, reflection, phone, and wearabledatalayer.
  • Create a project folder – something like DMWear
  • Extract the contents of the attached zip file to the project folder maintaining the directory structure.
  • With no devices connected, compile dmwear.b4a in the wearable folder to produce dmwear.apk (ignore the "no device found" compile warning)
  • Within mobile/Objects/res create xml and raw folders (mobile/Objects/res/xml and mobile/Objects/res/raw).
  • Copy the mobile/Files/wearable_app_desc.xml file to the xml folder you just created.
  • Copy the wearable/Objects/dmwear.apk file to the raw folder you just created.
  • Now open the mobile/dmmobile.b4a file in B4A, connect to your mobile device using the B4A Bridge or USB.
  • Compile and run. As the app installs itself on your mobile, the wearable apps will automatically install on the wearable devices. On my devices installation of the wearable apps takes about 90 seconds – be patient. The apps on the wearable devices will show up as DMWear.
Run the apps on both the mobile and wearable devices. Pressing the Add Data button will transfer a PNG from the mobile to the wearable. The text displays on both devices essentially contain log statements. You will see confirmation messages that the file transferred successfully.

Barry.
 

Attachments

  • DMWear.zip
    104.9 KB · Views: 239
Last edited:

FMFREAK

Member
Licensed User
Longtime User
Why I try the Static example, I get an: Unknown type: wearablelistener error. What do I do wrong ?
 

potman100

Active Member
Licensed User
Longtime User
Do not know if it matters, but the version I have is Version 1.00, have a look for the updated Library
 

Tim Green

Member
Licensed User
Longtime User
Cannot send messages to more than one paired device

Using the Wearable DataLayer 1.0 library I have communication working well (Thank you! barx) between a Nexus 10 tablet and a single paired Moto360 watch. Similar to the examples in the library thread, I process the Results list in the NodeResults event to find the Node maps and save and then use these when transmitting short messages using the Send method. There is normally only one Node map in the Results list. The Nexus 10 finds the node for the Moto360, and the Moto360 finds the node for the Nexus 10.

When I pair a second Moto360 with the Nexus 10, as expected, the Results list in the NodeResults event then returns two node maps. The Nexus 10 finds both Moto360's, and each Moto360 finds the Nexus 10 and the other Moto360.

Since I save both node maps in each of the devices I expected to use these to direct where the Send method transmits its messages to. But I found that it does not matter which node map is used in the Send method, all messages are transmitted to only one device. The pattern which has become apparent is that each device only transmits messages to the last node of the Results list provided in the NodeResults event.

Is this a bug? Or am I confused about how it should work? Does anyone have experience using this library to communicate with more than one Wearable?

The setup to test this somewhat involved. I can create simplified apps for the Nexus and Moto360's to demonstrate the issue.

The API note about the Send method:

Send (NodeID As String, Timeout As Long, msgPath As String, Data As String)
Sends a message to a specified node
NodeID - The ID of the node to connect to.


As a test I replaced the NodeID parameter with a dummy string and the behavior did not change, the message was still transmitted to the last Node found in the Results list provided in the NodeResults event. Perhaps this is the default behavior if the NodeID is invalid?

Thanks. - Tim Green
 

canalrun

Well-Known Member
Licensed User
Longtime User
Hello,
Yes, I've transmitted to multiple devices. Instead of saving the last connected node address you need to save all connected node addresses (I save them in a list).

Take a look at the three examples I've posted it earlier in this thread. I believe they all are set up to send to multiple devices.

Barry.
 

Tim Green

Member
Licensed User
Longtime User
[
Hello,
Yes, I've transmitted to multiple devices. Instead of saving the last connected node address you need to save all connected node addresses (I save them in a list).

Take a look at the three examples I've posted it earlier in this thread. I believe they all are set up to send to multiple devices.

Barry.

Thanks Barry. I looked again at the examples. I made a change in my code which should not have made any difference, but it did, and now it works OK.

In the NodeResults event the node maps and node ID strings are saved. Actually done in a loop with indexes but the simplified code does this:

‘ Save first node map and node ID string
Node = Results.Get( 0 ) ‘ Get the first node map from the Results list
Node1 = Node ‘ Node1 is a Map
NodeID1 = Node.Get( "ID" ) ‘ NodeID1 is a String

‘ Save second node map and node ID string
Node = Results.Get( 1 ) ‘ Get the second node map from the Results list
Node2 = Node ‘ Node2 is a Map
NodeID2 = Node.Get( "ID" ) ‘ NodeID2 is a String​

Later, this code results in sending both messages to Node2:
DL.message.Send( Node1.Get( "ID" ), 1000, "/to_1", Message1 )
DL.message.Send( Node2.Get( "ID" ), 1000, "/to_2", Message2 )​

But changing it to directly use the saved ID string works OK. A message is sent to Node 1 and a message is sent to Node 2.
DL.message.Send(NodeID1, 1000, "/to_1", Message1 )
DL.message.Send(NodeID2, 1000, "/to_2", Message2 )​

Do not know why this makes any difference, but happy to have it working OK.

Tim
 

barx

Well-Known Member
Licensed User
Longtime User
[


Thanks Barry. I looked again at the examples. I made a change in my code which should not have made any difference, but it did, and now it works OK.

In the NodeResults event the node maps and node ID strings are saved. Actually done in a loop with indexes but the simplified code does this:

‘ Save first node map and node ID string
Node = Results.Get( 0 ) ‘ Get the first node map from the Results list
Node1 = Node ‘ Node1 is a Map
NodeID1 = Node.Get( "ID" ) ‘ NodeID1 is a String

‘ Save second node map and node ID string
Node = Results.Get( 1 ) ‘ Get the second node map from the Results list
Node2 = Node ‘ Node2 is a Map
NodeID2 = Node.Get( "ID" ) ‘ NodeID2 is a String​

Later, this code results in sending both messages to Node2:
DL.message.Send( Node1.Get( "ID" ), 1000, "/to_1", Message1 )
DL.message.Send( Node2.Get( "ID" ), 1000, "/to_2", Message2 )​

But changing it to directly use the saved ID string works OK. A message is sent to Node 1 and a message is sent to Node 2.
DL.message.Send(NodeID1, 1000, "/to_1", Message1 )
DL.message.Send(NodeID2, 1000, "/to_2", Message2 )​

Do not know why this makes any difference, but happy to have it working OK.

Tim

The way b4a works means that when you do
B4X:
Node1 = Node
Node1 now holds a reference to Node, NOT a copy of the Node object.

Therefore when you have also done
B4X:
Node2 = Node
Then Node1 and Node2 now hold reference to the same node object.

Glad you got sorted in the end and well done @canalrun for helping out....
 

Jerez

Active Member
Licensed User
Longtime User
Examples

Each app that is made for Android Wear essentially contains 2 apps. One for the Wearable and one for the Mobile. the examples will come with both apps and the wearable pre-embedded in the mobile app.

Unfortunately it appears the examples will be too large to upload here so for now I will add them to my DropBox account and post links. If anybody knows a better solution........

Example 1: Simple messages with static listener

Very simple example show one way messages from mobile to wearable. the wearable uses a static listener so messages are received even if the app is closed. This example simply creates a ToastMessageShow() to show the message.

Download Link

Example 2: Simple messages with dynamic listener

Similar to example 1 but this one uses dynamic listener. This means that the messages will only be received on the wearable when the app is active. For anyone that doesn't know yet, to start an app: tap the screen, scroll down to bottom and pat 'Start', find the app and tap it to launch...

Download Link


Hi @barx: I've tried the Dynamic listener sample... I've installed the SDK and changed the reference path... also i've copied the .jar files to my lib folder... and all compile ok and run on device but... crashed on this line at start:


thanks!

B4X:
Sub Activity_Resume

    'Connects the GoogleApiClient (used for the communications link). Calls _Connected once connection is successful
    DL.Connect
   
End Sub

B4X:
** Activity (main) Resume **
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:barxdroid.wearable.example.dynamicmessage
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
main_activity_resume (B4A line: 47)
DL.Connect
java.lang.NoSuchMethodError: com.google.android.gms.common.api.GoogleApiClient.connect
    at barxdroid.wearabledatalayer.WearableDataLayer.Connect(WearableDataLayer.java:94)
    at barxdroid.wearable.example.dynamicmessage.main._activity_resume(main.java:392)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at barxdroid.wearable.example.dynamicmessage.main.afterFirstLayout(main.java:108)
    at barxdroid.wearable.example.dynamicmessage.main.access$000(main.java:17)
    at barxdroid.wearable.example.dynamicmessage.main$WaitForLayout.run(main.java:80)
    at android.os.Handler.handleCallback(Handler.java:808)
    at android.os.Handler.dispatchMessage(Handler.java:103)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:5407)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:855)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:671)
    at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
 

Attachments

  • googleplay.PNG
    googleplay.PNG
    52.9 KB · Views: 189

barx

Well-Known Member
Licensed User
Longtime User
Hi @barx: I've tried the Dynamic listener sample... I've installed the SDK and changed the reference path... also i've copied the .jar files to my lib folder... and all compile ok and run on device but... crashed on this line at start:


thanks!

B4X:
Sub Activity_Resume

    'Connects the GoogleApiClient (used for the communications link). Calls _Connected once connection is successful
    DL.Connect
  
End Sub

B4X:
** Activity (main) Resume **
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:barxdroid.wearable.example.dynamicmessage
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
main_activity_resume (B4A line: 47)
DL.Connect
java.lang.NoSuchMethodError: com.google.android.gms.common.api.GoogleApiClient.connect
    at barxdroid.wearabledatalayer.WearableDataLayer.Connect(WearableDataLayer.java:94)
    at barxdroid.wearable.example.dynamicmessage.main._activity_resume(main.java:392)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at barxdroid.wearable.example.dynamicmessage.main.afterFirstLayout(main.java:108)
    at barxdroid.wearable.example.dynamicmessage.main.access$000(main.java:17)
    at barxdroid.wearable.example.dynamicmessage.main$WaitForLayout.run(main.java:80)
    at android.os.Handler.handleCallback(Handler.java:808)
    at android.os.Handler.dispatchMessage(Handler.java:103)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:5407)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:855)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:671)
    at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **


Is the device already paired with a Wear device?
 
Top