Android WearListenerService OnData改变了奇怪的行为

Android WearListenerService OnData改变了奇怪的行为,android,wear-os,android-wear-data-api,Android,Wear Os,Android Wear Data Api,我想在Android Wear和掌上电脑之间进行双向数据传输。 除了在掌上电脑上改变触发数据外,一切似乎都很好。只有当我插入\拔出USB电缆并连接到电脑时,它才会触发。 所以我不明白为什么会这样 这是我的密码: 手持设备上的WearListenerService: import android.content.Intent; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; im

我想在Android Wear和掌上电脑之间进行双向数据传输。 除了在掌上电脑上改变触发数据外,一切似乎都很好。只有当我插入\拔出USB电缆并连接到电脑时,它才会触发。 所以我不明白为什么会这样

这是我的密码:

手持设备上的WearListenerService:

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;

import java.util.List;

import ru.orangesoftware.financisto.db.DatabaseAdapter;
import ru.orangesoftware.financisto.model.Category;
import ru.orangesoftware.financisto.model.CategoryTree;
import ru.orangesoftware.financisto.utils.Log;

public class WearService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener
{
    private static final String WEARABLE_DATA_PATH = "/wearable_data";
    private static final String HANDHELD_DATA_PATH = "/handheld_data";

    private SendToDataLayerThread s;
    GoogleApiClient googleClient;

    private DatabaseAdapter db;

    @Override
    public void onCreate()
    {
        super.onCreate();

        Log.d("WearService Created");
        db = new DatabaseAdapter(this);
        db.open();

        initGoogleApiClient();
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents)
    {
        Log.d("In dataChanged");

        DataMap dataMap;
        for (DataEvent event : dataEvents)
        {

            // Check the data type
            if (event.getType() == DataEvent.TYPE_CHANGED)
            {
                // Check the data path
                String path = event.getDataItem().getUri().getPath();
                if (path.equals(HANDHELD_DATA_PATH))
                {
                    dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                    Log.v("Path phone: " + path);
                    Log.v("DataMap received from watch: " + dataMap);

                    Intent messageIntent = new Intent();
                    messageIntent.setAction(Intent.ACTION_SEND);
                    messageIntent.putExtra("time", System.currentTimeMillis());
                    messageIntent.putExtra("DataMap", dataMap.toBundle());
                    LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);

                    // Create a DataMap object and send it to the data layer
                    dataMap = new DataMap();
                    dataMap.putString("Pong", "Pong" + String.valueOf(System.currentTimeMillis()));
                    dataMap.putLong("time", System.currentTimeMillis());

                    //Requires a new thread to avoid blocking the UI
                    s = new SendToDataLayerThread(WEARABLE_DATA_PATH, dataMap);
                    s.start();
                }
            }
        }
    }

    private void initGoogleApiClient()
    {
        // Build a new GoogleApiClient for the the Wearable API

        Log.d("Initialaizing GoogleClient");

        if (googleClient == null)
        {
            googleClient = new GoogleApiClient.Builder(this)
                    .addApi(Wearable.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }

        if (!googleClient.isConnected())
        {
            Log.d("Tring to connect to GoogleApi...");

            googleClient.connect();

        }

        Log.d("Google Client ID = " + googleClient.toString());
    }

    // Disconnect from the data layer when the Activity stops
    @Override
    public void onDestroy()
    {
        super.onDestroy();

        Log.d("WearService: onDestroy");

        if (null != googleClient && googleClient.isConnected())
        {
            googleClient.disconnect();
        }

        if (db != null)
        {
            db.close();
        }

    }



  @Override
public void onConnected(Bundle bundle)
{
    Log.d("onConnected entered");
    Log.d("GoogleAPI now status:" + googleClient.isConnected());
}

    @Override
    public void onConnectionSuspended(int i)
    {

    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.e("Connection to google api has failed. " + result.getErrorMessage());
    }

    class SendToDataLayerThread extends Thread
    {
        String path;
        DataMap dataMap;

        // Constructor for sending data objects to the data layer
        SendToDataLayerThread(String p, DataMap data)
        {
            path = p;
            dataMap = data;
        }

        public void run()
        {
            NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
            for (Node node : nodes.getNodes())
            {

                // Construct a DataRequest and send over the data layer
                PutDataMapRequest putDMR = PutDataMapRequest.create(path);
                putDMR.getDataMap().putAll(dataMap);
                PutDataRequest request = putDMR.asPutDataRequest();
                DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleClient, request).await();
                if (result.getStatus().isSuccess())
                {
                    Log.v("DataMap: " + dataMap + " sent to: " + node.getDisplayName() + "; path=" + path);
                } else
                {
                    // Log an error
                    Log.v("ERROR: failed to send DataMap");
                }
            }
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest package="ru.orangesoftware.financisto"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-feature android:name="android.hardware.type.watch"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.DeviceDefault">

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version"/>

        <activity
            android:name=".MainWearActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <service
            android:name="ru.orangesoftware.financisto.ListenerService"
            android:enabled="true">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.BIND_LISTENER"/>
            </intent-filter>
        </service>


    </application>

</manifest>
11-15 12:24:25.301 2460-2460/ru.orangesoftware.financisto D/FinancistoWear: onStartCommand: Service was started.
11-15 12:24:25.377 2460-2460/ru.orangesoftware.financisto V/FinancistoWear: DataMap: {time=1447565065308, ping=ping1447565065306} sent to: Tolive GN3
11-15 12:24:25.379 2460-3309/ru.orangesoftware.financisto D/FinancistoWear: In dataChanged
11-15 12:24:25.379 2460-3309/ru.orangesoftware.financisto D/FinancistoWear: DataChanged: path = /handheld_data
佩戴式耳机佩戴时的服务

import android.content.Intent;
import android.os.Bundle;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;

public class ListenerService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener
{
    private static final String WEARABLE_DATA_PATH = "/wearable_data";
    private static final String HANDHELD_DATA_PATH = "/handheld_data";

    GoogleApiClient googleClient;

    private SendToDataLayerThread s;

    @Override
    public void onDataChanged(DataEventBuffer dataEvents)
    {
        Log.d("In dataChanged");

        DataMap dataMap;
        for (DataEvent event : dataEvents)
        {
            // Check the data type
            if (event.getType() == DataEvent.TYPE_CHANGED)
            {
                // Check the data path
                String path = event.getDataItem().getUri().getPath();
                Log.d("DataChanged: " + "path = " + path);
                if (path.equals(WEARABLE_DATA_PATH))
                {
                    dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                    Log.d("DataChanged: " + "dataMap received on watch: " + dataMap);
                }

            }
        }
    }

    private void initGoogleApiClient()
    {
        if (googleClient == null)
        {
            Log.d("Building google client id...");
            googleClient = new GoogleApiClient.Builder(this)
                    .addApi(Wearable.API)
                            .addConnectionCallbacks(this)
                            .addOnConnectionFailedListener(this)
                    .build();

            Log.d("Google client id = " + googleClient.toString());
        }

        if (!googleClient.isConnected())
        {
            googleClient.connect();
        }

        Log.d("Google Client ID = " + googleClient.toString());
    }

    // Placeholders for required connection callbacks
    @Override
    public void onConnectionSuspended(int cause)
    {
    }

    @Override
    public void onConnected(Bundle connectionHint)
    {
        Log.v("OnConnected entered");
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult)
    {
    }

    // Connect to the data layer when the Activity starts
    @Override
    public void onCreate()
    {
        super.onCreate();
        initGoogleApiClient();
    }

    // Disconnect from the data layer when the Activity stops
    @Override
    public void onDestroy()
    {
        if (null != googleClient && googleClient.isConnected())
        {
            Log.d("onDestroy: Disconnecting googleClient");
            googleClient.disconnect();
        }

        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startid)
    {
        Log.d("onStartCommand: Service was started.");

        // Create a DataMap object and send it to the data layer
        DataMap dataMap = new DataMap();
        dataMap.putString("ping", "ping" + String.valueOf(System.currentTimeMillis()));
        dataMap.putLong("time", System.currentTimeMillis());
        //Requires a new thread to avoid blocking the UI

        s = new SendToDataLayerThread(HANDHELD_DATA_PATH, dataMap);
        s.start();

        return super.onStartCommand(intent, flags, startid);
    }

    class SendToDataLayerThread extends Thread
    {
        String path;
        DataMap dataMap;

        // Constructor for sending data objects to the data layer
        SendToDataLayerThread(String p, DataMap data)
        {
            path = p;
            dataMap = data;
        }

        public void run()
        {
            NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
            for (Node node : nodes.getNodes())
            {

                final Node node2 = node;

                // Construct a DataRequest and send over the data layer
                PutDataMapRequest putDMR = PutDataMapRequest.create(path);
                putDMR.getDataMap().putAll(dataMap);
                PutDataRequest request = putDMR.asPutDataRequest();

                PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(googleClient, request);
                pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>()
                {
                    @Override
                    public void onResult(DataApi.DataItemResult dataItemResult)
                    {
                        if (dataItemResult.getStatus().isSuccess())
                        {
                            Log.v("DataMap: " + dataMap + " sent to: " + node2.getDisplayName());
                        } else
                        {
                            // Log an error
                            Log.v("ERROR: failed to send DataMap");
                        }
                    }
                });


            }
        }
    }
}
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

repositories {
    maven { url "http://repo.commonsware.com.s3.amazonaws.com" }
    maven { url "https://repository-achartengine.forge.cloudbees.com/snapshot/" }
    mavenCentral()
}

android {
    compileSdkVersion 22
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "ru.orangesoftware.financisto"
        minSdkVersion 19
        targetSdkVersion 22
        versionCode 92
        versionName "1.6.8"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
    }
}

def googlePlayVersion = '8.3.0'

dependencies {
    compile "com.google.android.gms:play-services-base:$googlePlayVersion"
    compile "com.google.android.gms:play-services-drive:$googlePlayVersion"
    compile "com.google.android.gms:play-services-wearable:$googlePlayVersion"

    compile files('libs/dropbox-android-sdk-1.6.1/dropbox-android-sdk-1.6.1.jar')
    compile files('libs/google-rfc-2445/rfc2445-no-joda.jar')
    compile 'com.google.code.gson:gson:2.3'
    compile 'com.commonsware.cwac:wakeful:1.0.1'
    compile 'org.achartengine:achartengine:1.2.0'
    compile 'net.sf.trove4j:trove4j:3.0.3'
    compile 'com.wdullaer:materialdatetimepicker:2.0.0'
}
apply plugin: 'com.android.application'


android {
    compileSdkVersion 22
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "ru.orangesoftware.financisto"
        minSdkVersion 20
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

def googlePlayVersion = '8.3.0'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.support:wearable:1.3.0'
    compile "com.google.android.gms:play-services-wearable:$googlePlayVersion"
}
11-15 12:20:20.616 29043-29043/? D/Financisto: WearService Created [WearService.onCreate:44]
11-15 12:20:20.616 29043-29043/? D/Financisto: Initialaizing GoogleClient [WearService.initGoogleApiClient:94]
11-15 12:20:20.636 29043-29043/? D/Financisto: Tring to connect to GoogleApi... [WearService.initGoogleApiClient:107]
11-15 12:20:20.636 29043-29043/? D/Financisto: Google Client ID = com.google.android.gms.internal.zzmg@4344d5c0 [WearService.initGoogleApiClient:113]
11-15 12:20:21.016 29043-29043/ru.orangesoftware.financisto D/Financisto: onConnected entered [WearService.onConnected:139]
11-15 12:20:21.016 29043-29043/ru.orangesoftware.financisto D/Financisto: GoogleAPI now status:true [WearService.onConnected:140]

-------now I send data from watch and unplug usb cable after 30 seconds

11-15 12:24:31.986 29043-29091/? D/Financisto: In dataChanged [WearService.onDataChanged:54]
11-15 12:24:31.986 29043-29091/? V/Financisto: Path phone: /handheld_data [WearService.onDataChanged:68]
11-15 12:24:31.986 29043-29091/? V/Financisto: DataMap received from watch: {time=1447565065308, ping=ping1447565065306} [WearService.onDataChanged:69]
11-15 12:24:32.036 29043-29091/? D/Financisto: In dataChanged [WearService.onDataChanged:54]
11-15 12:24:32.046 29043-1493/? V/Financisto: DataMap: {Pong=Pong1447565071992, time=1447565071992} sent to: Gear 2 76A1; path=/wearable_data [SendToDataLayerThread.run:179]
渐变磨损

import android.content.Intent;
import android.os.Bundle;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;

public class ListenerService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener
{
    private static final String WEARABLE_DATA_PATH = "/wearable_data";
    private static final String HANDHELD_DATA_PATH = "/handheld_data";

    GoogleApiClient googleClient;

    private SendToDataLayerThread s;

    @Override
    public void onDataChanged(DataEventBuffer dataEvents)
    {
        Log.d("In dataChanged");

        DataMap dataMap;
        for (DataEvent event : dataEvents)
        {
            // Check the data type
            if (event.getType() == DataEvent.TYPE_CHANGED)
            {
                // Check the data path
                String path = event.getDataItem().getUri().getPath();
                Log.d("DataChanged: " + "path = " + path);
                if (path.equals(WEARABLE_DATA_PATH))
                {
                    dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                    Log.d("DataChanged: " + "dataMap received on watch: " + dataMap);
                }

            }
        }
    }

    private void initGoogleApiClient()
    {
        if (googleClient == null)
        {
            Log.d("Building google client id...");
            googleClient = new GoogleApiClient.Builder(this)
                    .addApi(Wearable.API)
                            .addConnectionCallbacks(this)
                            .addOnConnectionFailedListener(this)
                    .build();

            Log.d("Google client id = " + googleClient.toString());
        }

        if (!googleClient.isConnected())
        {
            googleClient.connect();
        }

        Log.d("Google Client ID = " + googleClient.toString());
    }

    // Placeholders for required connection callbacks
    @Override
    public void onConnectionSuspended(int cause)
    {
    }

    @Override
    public void onConnected(Bundle connectionHint)
    {
        Log.v("OnConnected entered");
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult)
    {
    }

    // Connect to the data layer when the Activity starts
    @Override
    public void onCreate()
    {
        super.onCreate();
        initGoogleApiClient();
    }

    // Disconnect from the data layer when the Activity stops
    @Override
    public void onDestroy()
    {
        if (null != googleClient && googleClient.isConnected())
        {
            Log.d("onDestroy: Disconnecting googleClient");
            googleClient.disconnect();
        }

        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startid)
    {
        Log.d("onStartCommand: Service was started.");

        // Create a DataMap object and send it to the data layer
        DataMap dataMap = new DataMap();
        dataMap.putString("ping", "ping" + String.valueOf(System.currentTimeMillis()));
        dataMap.putLong("time", System.currentTimeMillis());
        //Requires a new thread to avoid blocking the UI

        s = new SendToDataLayerThread(HANDHELD_DATA_PATH, dataMap);
        s.start();

        return super.onStartCommand(intent, flags, startid);
    }

    class SendToDataLayerThread extends Thread
    {
        String path;
        DataMap dataMap;

        // Constructor for sending data objects to the data layer
        SendToDataLayerThread(String p, DataMap data)
        {
            path = p;
            dataMap = data;
        }

        public void run()
        {
            NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
            for (Node node : nodes.getNodes())
            {

                final Node node2 = node;

                // Construct a DataRequest and send over the data layer
                PutDataMapRequest putDMR = PutDataMapRequest.create(path);
                putDMR.getDataMap().putAll(dataMap);
                PutDataRequest request = putDMR.asPutDataRequest();

                PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(googleClient, request);
                pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>()
                {
                    @Override
                    public void onResult(DataApi.DataItemResult dataItemResult)
                    {
                        if (dataItemResult.getStatus().isSuccess())
                        {
                            Log.v("DataMap: " + dataMap + " sent to: " + node2.getDisplayName());
                        } else
                        {
                            // Log an error
                            Log.v("ERROR: failed to send DataMap");
                        }
                    }
                });


            }
        }
    }
}
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

repositories {
    maven { url "http://repo.commonsware.com.s3.amazonaws.com" }
    maven { url "https://repository-achartengine.forge.cloudbees.com/snapshot/" }
    mavenCentral()
}

android {
    compileSdkVersion 22
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "ru.orangesoftware.financisto"
        minSdkVersion 19
        targetSdkVersion 22
        versionCode 92
        versionName "1.6.8"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
    }
}

def googlePlayVersion = '8.3.0'

dependencies {
    compile "com.google.android.gms:play-services-base:$googlePlayVersion"
    compile "com.google.android.gms:play-services-drive:$googlePlayVersion"
    compile "com.google.android.gms:play-services-wearable:$googlePlayVersion"

    compile files('libs/dropbox-android-sdk-1.6.1/dropbox-android-sdk-1.6.1.jar')
    compile files('libs/google-rfc-2445/rfc2445-no-joda.jar')
    compile 'com.google.code.gson:gson:2.3'
    compile 'com.commonsware.cwac:wakeful:1.0.1'
    compile 'org.achartengine:achartengine:1.2.0'
    compile 'net.sf.trove4j:trove4j:3.0.3'
    compile 'com.wdullaer:materialdatetimepicker:2.0.0'
}
apply plugin: 'com.android.application'


android {
    compileSdkVersion 22
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "ru.orangesoftware.financisto"
        minSdkVersion 20
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

def googlePlayVersion = '8.3.0'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.support:wearable:1.3.0'
    compile "com.google.android.gms:play-services-wearable:$googlePlayVersion"
}
11-15 12:20:20.616 29043-29043/? D/Financisto: WearService Created [WearService.onCreate:44]
11-15 12:20:20.616 29043-29043/? D/Financisto: Initialaizing GoogleClient [WearService.initGoogleApiClient:94]
11-15 12:20:20.636 29043-29043/? D/Financisto: Tring to connect to GoogleApi... [WearService.initGoogleApiClient:107]
11-15 12:20:20.636 29043-29043/? D/Financisto: Google Client ID = com.google.android.gms.internal.zzmg@4344d5c0 [WearService.initGoogleApiClient:113]
11-15 12:20:21.016 29043-29043/ru.orangesoftware.financisto D/Financisto: onConnected entered [WearService.onConnected:139]
11-15 12:20:21.016 29043-29043/ru.orangesoftware.financisto D/Financisto: GoogleAPI now status:true [WearService.onConnected:140]

-------now I send data from watch and unplug usb cable after 30 seconds

11-15 12:24:31.986 29043-29091/? D/Financisto: In dataChanged [WearService.onDataChanged:54]
11-15 12:24:31.986 29043-29091/? V/Financisto: Path phone: /handheld_data [WearService.onDataChanged:68]
11-15 12:24:31.986 29043-29091/? V/Financisto: DataMap received from watch: {time=1447565065308, ping=ping1447565065306} [WearService.onDataChanged:69]
11-15 12:24:32.036 29043-29091/? D/Financisto: In dataChanged [WearService.onDataChanged:54]
11-15 12:24:32.046 29043-1493/? V/Financisto: DataMap: {Pong=Pong1447565071992, time=1447565071992} sent to: Gear 2 76A1; path=/wearable_data [SendToDataLayerThread.run:179]
在应用程序启动后登录掌上电脑

import android.content.Intent;
import android.os.Bundle;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;

public class ListenerService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener
{
    private static final String WEARABLE_DATA_PATH = "/wearable_data";
    private static final String HANDHELD_DATA_PATH = "/handheld_data";

    GoogleApiClient googleClient;

    private SendToDataLayerThread s;

    @Override
    public void onDataChanged(DataEventBuffer dataEvents)
    {
        Log.d("In dataChanged");

        DataMap dataMap;
        for (DataEvent event : dataEvents)
        {
            // Check the data type
            if (event.getType() == DataEvent.TYPE_CHANGED)
            {
                // Check the data path
                String path = event.getDataItem().getUri().getPath();
                Log.d("DataChanged: " + "path = " + path);
                if (path.equals(WEARABLE_DATA_PATH))
                {
                    dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                    Log.d("DataChanged: " + "dataMap received on watch: " + dataMap);
                }

            }
        }
    }

    private void initGoogleApiClient()
    {
        if (googleClient == null)
        {
            Log.d("Building google client id...");
            googleClient = new GoogleApiClient.Builder(this)
                    .addApi(Wearable.API)
                            .addConnectionCallbacks(this)
                            .addOnConnectionFailedListener(this)
                    .build();

            Log.d("Google client id = " + googleClient.toString());
        }

        if (!googleClient.isConnected())
        {
            googleClient.connect();
        }

        Log.d("Google Client ID = " + googleClient.toString());
    }

    // Placeholders for required connection callbacks
    @Override
    public void onConnectionSuspended(int cause)
    {
    }

    @Override
    public void onConnected(Bundle connectionHint)
    {
        Log.v("OnConnected entered");
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult)
    {
    }

    // Connect to the data layer when the Activity starts
    @Override
    public void onCreate()
    {
        super.onCreate();
        initGoogleApiClient();
    }

    // Disconnect from the data layer when the Activity stops
    @Override
    public void onDestroy()
    {
        if (null != googleClient && googleClient.isConnected())
        {
            Log.d("onDestroy: Disconnecting googleClient");
            googleClient.disconnect();
        }

        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startid)
    {
        Log.d("onStartCommand: Service was started.");

        // Create a DataMap object and send it to the data layer
        DataMap dataMap = new DataMap();
        dataMap.putString("ping", "ping" + String.valueOf(System.currentTimeMillis()));
        dataMap.putLong("time", System.currentTimeMillis());
        //Requires a new thread to avoid blocking the UI

        s = new SendToDataLayerThread(HANDHELD_DATA_PATH, dataMap);
        s.start();

        return super.onStartCommand(intent, flags, startid);
    }

    class SendToDataLayerThread extends Thread
    {
        String path;
        DataMap dataMap;

        // Constructor for sending data objects to the data layer
        SendToDataLayerThread(String p, DataMap data)
        {
            path = p;
            dataMap = data;
        }

        public void run()
        {
            NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
            for (Node node : nodes.getNodes())
            {

                final Node node2 = node;

                // Construct a DataRequest and send over the data layer
                PutDataMapRequest putDMR = PutDataMapRequest.create(path);
                putDMR.getDataMap().putAll(dataMap);
                PutDataRequest request = putDMR.asPutDataRequest();

                PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(googleClient, request);
                pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>()
                {
                    @Override
                    public void onResult(DataApi.DataItemResult dataItemResult)
                    {
                        if (dataItemResult.getStatus().isSuccess())
                        {
                            Log.v("DataMap: " + dataMap + " sent to: " + node2.getDisplayName());
                        } else
                        {
                            // Log an error
                            Log.v("ERROR: failed to send DataMap");
                        }
                    }
                });


            }
        }
    }
}
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

repositories {
    maven { url "http://repo.commonsware.com.s3.amazonaws.com" }
    maven { url "https://repository-achartengine.forge.cloudbees.com/snapshot/" }
    mavenCentral()
}

android {
    compileSdkVersion 22
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "ru.orangesoftware.financisto"
        minSdkVersion 19
        targetSdkVersion 22
        versionCode 92
        versionName "1.6.8"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
    }
}

def googlePlayVersion = '8.3.0'

dependencies {
    compile "com.google.android.gms:play-services-base:$googlePlayVersion"
    compile "com.google.android.gms:play-services-drive:$googlePlayVersion"
    compile "com.google.android.gms:play-services-wearable:$googlePlayVersion"

    compile files('libs/dropbox-android-sdk-1.6.1/dropbox-android-sdk-1.6.1.jar')
    compile files('libs/google-rfc-2445/rfc2445-no-joda.jar')
    compile 'com.google.code.gson:gson:2.3'
    compile 'com.commonsware.cwac:wakeful:1.0.1'
    compile 'org.achartengine:achartengine:1.2.0'
    compile 'net.sf.trove4j:trove4j:3.0.3'
    compile 'com.wdullaer:materialdatetimepicker:2.0.0'
}
apply plugin: 'com.android.application'


android {
    compileSdkVersion 22
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "ru.orangesoftware.financisto"
        minSdkVersion 20
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

def googlePlayVersion = '8.3.0'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.support:wearable:1.3.0'
    compile "com.google.android.gms:play-services-wearable:$googlePlayVersion"
}
11-15 12:20:20.616 29043-29043/? D/Financisto: WearService Created [WearService.onCreate:44]
11-15 12:20:20.616 29043-29043/? D/Financisto: Initialaizing GoogleClient [WearService.initGoogleApiClient:94]
11-15 12:20:20.636 29043-29043/? D/Financisto: Tring to connect to GoogleApi... [WearService.initGoogleApiClient:107]
11-15 12:20:20.636 29043-29043/? D/Financisto: Google Client ID = com.google.android.gms.internal.zzmg@4344d5c0 [WearService.initGoogleApiClient:113]
11-15 12:20:21.016 29043-29043/ru.orangesoftware.financisto D/Financisto: onConnected entered [WearService.onConnected:139]
11-15 12:20:21.016 29043-29043/ru.orangesoftware.financisto D/Financisto: GoogleAPI now status:true [WearService.onConnected:140]

-------now I send data from watch and unplug usb cable after 30 seconds

11-15 12:24:31.986 29043-29091/? D/Financisto: In dataChanged [WearService.onDataChanged:54]
11-15 12:24:31.986 29043-29091/? V/Financisto: Path phone: /handheld_data [WearService.onDataChanged:68]
11-15 12:24:31.986 29043-29091/? V/Financisto: DataMap received from watch: {time=1447565065308, ping=ping1447565065306} [WearService.onDataChanged:69]
11-15 12:24:32.036 29043-29091/? D/Financisto: In dataChanged [WearService.onDataChanged:54]
11-15 12:24:32.046 29043-1493/? V/Financisto: DataMap: {Pong=Pong1447565071992, time=1447565071992} sent to: Gear 2 76A1; path=/wearable_data [SendToDataLayerThread.run:179]
在应用程序启动和数据发送后登录:

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;

import java.util.List;

import ru.orangesoftware.financisto.db.DatabaseAdapter;
import ru.orangesoftware.financisto.model.Category;
import ru.orangesoftware.financisto.model.CategoryTree;
import ru.orangesoftware.financisto.utils.Log;

public class WearService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener
{
    private static final String WEARABLE_DATA_PATH = "/wearable_data";
    private static final String HANDHELD_DATA_PATH = "/handheld_data";

    private SendToDataLayerThread s;
    GoogleApiClient googleClient;

    private DatabaseAdapter db;

    @Override
    public void onCreate()
    {
        super.onCreate();

        Log.d("WearService Created");
        db = new DatabaseAdapter(this);
        db.open();

        initGoogleApiClient();
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents)
    {
        Log.d("In dataChanged");

        DataMap dataMap;
        for (DataEvent event : dataEvents)
        {

            // Check the data type
            if (event.getType() == DataEvent.TYPE_CHANGED)
            {
                // Check the data path
                String path = event.getDataItem().getUri().getPath();
                if (path.equals(HANDHELD_DATA_PATH))
                {
                    dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                    Log.v("Path phone: " + path);
                    Log.v("DataMap received from watch: " + dataMap);

                    Intent messageIntent = new Intent();
                    messageIntent.setAction(Intent.ACTION_SEND);
                    messageIntent.putExtra("time", System.currentTimeMillis());
                    messageIntent.putExtra("DataMap", dataMap.toBundle());
                    LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);

                    // Create a DataMap object and send it to the data layer
                    dataMap = new DataMap();
                    dataMap.putString("Pong", "Pong" + String.valueOf(System.currentTimeMillis()));
                    dataMap.putLong("time", System.currentTimeMillis());

                    //Requires a new thread to avoid blocking the UI
                    s = new SendToDataLayerThread(WEARABLE_DATA_PATH, dataMap);
                    s.start();
                }
            }
        }
    }

    private void initGoogleApiClient()
    {
        // Build a new GoogleApiClient for the the Wearable API

        Log.d("Initialaizing GoogleClient");

        if (googleClient == null)
        {
            googleClient = new GoogleApiClient.Builder(this)
                    .addApi(Wearable.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }

        if (!googleClient.isConnected())
        {
            Log.d("Tring to connect to GoogleApi...");

            googleClient.connect();

        }

        Log.d("Google Client ID = " + googleClient.toString());
    }

    // Disconnect from the data layer when the Activity stops
    @Override
    public void onDestroy()
    {
        super.onDestroy();

        Log.d("WearService: onDestroy");

        if (null != googleClient && googleClient.isConnected())
        {
            googleClient.disconnect();
        }

        if (db != null)
        {
            db.close();
        }

    }



  @Override
public void onConnected(Bundle bundle)
{
    Log.d("onConnected entered");
    Log.d("GoogleAPI now status:" + googleClient.isConnected());
}

    @Override
    public void onConnectionSuspended(int i)
    {

    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.e("Connection to google api has failed. " + result.getErrorMessage());
    }

    class SendToDataLayerThread extends Thread
    {
        String path;
        DataMap dataMap;

        // Constructor for sending data objects to the data layer
        SendToDataLayerThread(String p, DataMap data)
        {
            path = p;
            dataMap = data;
        }

        public void run()
        {
            NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
            for (Node node : nodes.getNodes())
            {

                // Construct a DataRequest and send over the data layer
                PutDataMapRequest putDMR = PutDataMapRequest.create(path);
                putDMR.getDataMap().putAll(dataMap);
                PutDataRequest request = putDMR.asPutDataRequest();
                DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleClient, request).await();
                if (result.getStatus().isSuccess())
                {
                    Log.v("DataMap: " + dataMap + " sent to: " + node.getDisplayName() + "; path=" + path);
                } else
                {
                    // Log an error
                    Log.v("ERROR: failed to send DataMap");
                }
            }
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest package="ru.orangesoftware.financisto"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-feature android:name="android.hardware.type.watch"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.DeviceDefault">

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version"/>

        <activity
            android:name=".MainWearActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <service
            android:name="ru.orangesoftware.financisto.ListenerService"
            android:enabled="true">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.BIND_LISTENER"/>
            </intent-filter>
        </service>


    </application>

</manifest>
11-15 12:24:25.301 2460-2460/ru.orangesoftware.financisto D/FinancistoWear: onStartCommand: Service was started.
11-15 12:24:25.377 2460-2460/ru.orangesoftware.financisto V/FinancistoWear: DataMap: {time=1447565065308, ping=ping1447565065306} sent to: Tolive GN3
11-15 12:24:25.379 2460-3309/ru.orangesoftware.financisto D/FinancistoWear: In dataChanged
11-15 12:24:25.379 2460-3309/ru.orangesoftware.financisto D/FinancistoWear: DataChanged: path = /handheld_data
请告诉我,我做错了什么

解决方案

我重写了SendtoAtatalayerthread。现在它是一个常规类,没有扩展线程,DataRequest变得很紧急:

class SendToDataLayerThread
    {
        String path;
        DataMap dataMap;

        // Constructor for sending data objects to the data layer
        SendToDataLayerThread(String p, DataMap data)
        {
            path = p;
            dataMap = data;
        }

        public void run()
        {
            //NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient);
            PendingResult<NodeApi.GetConnectedNodesResult> nodes = Wearable.NodeApi.getConnectedNodes(googleClient);
            nodes.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>()
            {
                @Override
                public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult)
                {
                    for (Node node : getConnectedNodesResult.getNodes())
                    {

                        final Node node2 = node;

                        // Construct a DataRequest and send over the data layer
                        PutDataMapRequest putDMR = PutDataMapRequest.create(path);
                        putDMR.getDataMap().putAll(dataMap);
                        PutDataRequest request = putDMR.asPutDataRequest();
                        request.setUrgent();

                        PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(googleClient, request);
                        pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>()
                        {
                            @Override
                            public void onResult(DataApi.DataItemResult dataItemResult)
                            {
                                if (dataItemResult.getStatus().isSuccess())
                                {
                                    Log.v("DataMap: " + dataMap + " sent to: " + node2.getDisplayName());
                                } else
                                {
                                    // Log an error
                                    Log.v("ERROR: failed to send DataMap");
                                }
                            }
                        });
                    }
                }
            });
        }
    }
类SendToDataLayerThread
{
字符串路径;
数据地图;
//用于将数据对象发送到数据层的构造函数
SendToDataLayerThread(字符串p,数据映射数据)
{
path=p;
数据地图=数据;
}
公开募捐
{
//NodeApi.getConnectedNodeResult nodes=可穿戴的.NodeApi.getConnectedNodes(谷歌客户端);
Pendingreult节点=可穿戴的.NodeApi.getConnectedNodes(谷歌客户端);
setResultCallback(新的ResultCallback()
{
@凌驾
公共void onResult(NodeApi.GetConnectedNodesResult GetConnectedNodesResult)
{
对于(节点:GetConnectedNodeResult.getNodes())
{
最终节点node2=节点;
//构造DataRequest并通过数据层发送
PutDataMapRequest putDMR=PutDataMapRequest.create(路径);
putDMR.getDataMap().putAll(dataMap);
PutDataRequest=putDMR.asPutDataRequest();
request.setUrgent();
Pendingreult Pendingreult=Wearable.DataApi.putDataItem(谷歌客户端,请求);
Pendingreult.setResultCallback(新的ResultCallback()
{
@凌驾
public void onResult(DataApi.DataItemResult DataItemResult)
{
if(dataItemResult.getStatus().isSuccess())
{
Log.v(“DataMap:+DataMap+”发送到:“+node2.getDisplayName()”);
}否则
{
//记录错误
Log.v(“错误:无法发送数据映射”);
}
}
});
}
}
});
}
}
谢谢你的帮助

根据:

使用GooglePlayServices8.3,我们更新了DataApi,以便在同步数据项时考虑到紧迫性。现在,可以向数据项添加优先级,以确定何时应同步该数据项。例如,如果您正在构建一个需要立即同步的应用程序,例如远程控制应用程序,仍然可以通过调用setUrgent()立即完成同步,但对于更新联系人之类的操作,您可以容忍一些延迟非紧急数据项可能会延迟30分钟,但在大多数情况下,它们会在几分钟内送达低优先级现在是默认值,因此需要获取上一个计时


因此,如果您希望数据请求立即同步到其他连接的设备,请确保调用数据请求。

哇,谢谢,这解决了手持设备上的问题!(我将其添加到手持设备和穿戴设备中)。现在它立即触发了数据更改。在我将数据发送到掌上电脑后,我的穿戴是无声的。我试图在手持设备上重写发送过程,就像它在磨损一样,但什么都没有。现在我已经更改了手持设备的磨损请求。从日志中(与问题类似),我看到请求已成功发送到正确的设备,但onDataChanged on wear未接收到请求(无论是否使用setUrgent())。若我通过MessageApi从手持设备发送消息,那个么它将被磨损的附加onMessageReceived接收。我想知道一个秘密,为什么MessageApi工作得很好,而DataAPI在某个地方丢失了。我发现数据可以通过以下修改之一达到磨损:在发送数据后,在手持设备上制作googleapi disconnect()和connect(),或者将Thread.start()替换为Thread.run()我甚至不知道,当有异步版本可以用来代替在线程上调用
await()
时,为什么要旋转整个新线程。