B4A Library Wearable DataLayer

Discussion in 'Additional libraries, classes and official updates' started by barx, Jan 28, 2015.

  1. barx

    barx Well-Known Member Licensed User

    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

    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.
    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.............
     

    Attached Files:

  2. barx

    barx Well-Known Member Licensed 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
     
    Last edited: Mar 7, 2015
    Jerez, thedesolatesoul and NJDude like this.
  3. holdemadvantage

    holdemadvantage Active Member Licensed User

    Hi barx, how can i try an app on an android wear smartwatch? (how can i load apk to device)
    Thanks
     
  4. barx

    barx Well-Known Member Licensed User

    See the tutorial link I the first post. The wearable apk can also be installed direct from b4a like a normal device for testing.
     
    Last edited: Jan 29, 2015
  5. holdemadvantage

    holdemadvantage Active Member Licensed User

    Thanks barx i will try, no way to install apk directly on watch?
     
  6. barx

    barx Well-Known Member Licensed User

    Post 4 sentence 2.....
    There no way to install direct to watch from play store or direct apk link. But if you set your watch up for debugging then connect with USB and compile B4a.
     
    thedesolatesoul likes this.
  7. holdemadvantage

    holdemadvantage Active Member Licensed User

    Thanks, i am learning a lot from your posts, i have already bought a lg watch r and i am quite noob with wearable
     
    barx likes this.
  8. barx

    barx Well-Known Member Licensed User

    See post #2 for the first example

    thank you
     
    thedesolatesoul likes this.
  9. holdemadvantage

    holdemadvantage Active Member Licensed User

    Hi, i was able to debug my app on my lg watch r (it has not a sim).. is there some way to use interenet connection of paired device (i try to display a data with httputils2 with no luck). We can make only offline apps?
     
  10. barx

    barx Well-Known Member Licensed User

    You have to do the Internet part in the phone app and send info to watch using data map. I will try to explain later as I am currently stuck under a floor soldering pipes....
     
  11. holdemadvantage

    holdemadvantage Active Member Licensed User

    Thanks barx, it could be very useful
     
  12. barx

    barx Well-Known Member Licensed User

    Ok, the way I see this working is as follows.
    Use static listener service in mobile app.
    In your wearable app send a message to trigger the mobile app listener service then your listener service will do the http stuff and add a datamap to the wear network with the info.

    wearable the uses listener to get added data and use / display it


    I know it sounds crazy complicated but this is the way Wear works.....
     
    thedesolatesoul likes this.
  13. holdemadvantage

    holdemadvantage Active Member Licensed User

    Sounds great, it will be very useful an example of wearable app+listener app for example to display a string published in a webpage (could be a blank page with a string displayed), can you do it? Let us know, thanks in advance ;)
     
  14. barx

    barx Well-Known Member Licensed User

    I will have a go for you, but I cannot promise the time.....
     
  15. holdemadvantage

    holdemadvantage Active Member Licensed User

    Thanks in advance barx
     
  16. Ben Casavant

    Ben Casavant New Member Licensed User

    Hi, when trying to compile the app (my own and the example), I am faced with the following error: "class file for com.google.android.gms.wearable.DataApi not found". Do you have any suggestions? Thanks!
     
  17. barx

    barx Well-Known Member Licensed User


    Have you installed Google Play Services library from the Android SDK Manager and copied it to your B4A additional Libraries folder?
     
    thedesolatesoul likes this.
  18. Ben Casavant

    Ben Casavant New Member Licensed User

    Yep, but only the .jar file google-play-services.jar -> re-copied over this file and now it works, thanks!
     
    Last edited: Feb 11, 2015
    barx likes this.
  19. smishra

    smishra Member Licensed User

    Barx, would it be possible for you to add an example showing how to transfer files? I tried the following lines

    Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

    Dim DL As WearableDataLayer 'The DataLayer
    Dim WA As WearableAsset
    Dim DM As WearableDataMap
    End Sub

    Sub DL_Connected()
    DL.GetConnectedNodes 'returns the results in the _NodeResults event
    WA.CreateFromFile("/sdcard", "example.txt")
    DM.PutAsset("wear", WA)
    DL.AddDataMap("/test", DM)
    End Sub


    and get the following when I compile

    DM.PutAsset(\
    javac 1.7.0_45
    src\livonics\epidetect_wear\epidetectservice.java:114: error: inconvertible types
    _dm.PutAsset("wear",(com.google.android.gms.wearable.Asset)(_wa));
    ^
    required: Asset
    found: WearableAsset
     
  20. Peter Simpson

    Peter Simpson Expert Licensed User

    This is excellent @barx, cheers...
     
    barx likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice