0

我创建了一个带有 Activity 的移动应用程序,它发送数据以供穿戴。移动应用端代码如下

请注意,我删除了一些代码以减少行数。

public class MainActivity extends AppCompatActivity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener  {

    GoogleApiClient mGoogleClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Build a new GoogleApiClient for the the Wearable API
        mGoogleClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        Button sendBtn = (Button) findViewById(R.id.send_btn);
        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mGoogleClient.isConnected()) {
                    Log.w("mobile-p", "connected.....sending data");
                    sendData();

                }
            }
        });
    }

    // Connect to the data layer when the Activity starts
    @Override
    protected void onStart() {
        super.onStart();
        mGoogleClient.connect();
    }

    private void constructDataI temsForNotification() {
        //I construct the dataItems here which needs to be passed to the wear
        //and call the sendata.
        sendData();
    }

    private void sendData() {
        //Requires a new thread to avoid blocking the UI
        if (mDataMapList != null && mDataMapList.size() > 0 ) {
            new SendToDataLayerThread().start();
        } else {
            Log.w("mobile", "Nothing to notify");
        }
    }

    @Override
    public void onConnected(Bundle connectionHint) {
    }

    // Disconnect from the data layer when the Activity stops
    @Override
    protected void onStop() {
        if (null != mGoogleClient && mGoogleClient.isConnected()) {
            mGoogleClient.disconnect();
        }
        super.onStop();
    }

    // Placeholders for required connection callbacks
    @Override
    public void onConnectionSuspended(int cause) {
        if (mGoogleClient != null) {
            mGoogleClient.reconnect();
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) { }

    //Use thread or asynctask.
    class SendToDataLayerThread extends Thread {

        public void run() {
            // Construct a DataRequest and send over the data layer
            PutDataMapRequest putDMR = PutDataMapRequest.create("/weardatapath");
            putDMR.getDataMap().putDataMapArrayList("/weardatapath", mDataMapList);
            PutDataRequest request = putDMR.asPutDataRequest();
            DataApi.DataItemResult result = Wearable.DataApi.putDataItem(mGoogleClient, request).await();
            if (result.getStatus().isSuccess()) {
                for (DataMap mapItem : mDataMapList) {
                    Log.v("mobile-p", "DataMap: " + mapItem + " sent successfully to data layer ");
                }
            } else {
                // Log an error
                Log.v("mobile-p", "ERROR: failed to send DataMap to data layer");
            }
        }
    }
}

在 Wear 应用程序端,我创建了一个PhoneListenerService,如下所示

public class PhoneListenerService extends WearableListenerService {

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {

        DataMap dataMap;
        for (DataEvent event : dataEvents) {
            Log.v("Wear-W", "DataMap received on watch: " + DataMapItem.fromDataItem(event.getDataItem()).getDataMap());
            // Check the data type
            if (event.getType() == DataEvent.TYPE_CHANGED) {
                // Check the data path
                String path = event.getDataItem().getUri().getPath();
                if (path.equals("/weardatapath")) {
                    DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
                    ArrayList<DataMap> dataItems = dataMapItem.getDataMap().getDataMapArrayList
                            ("dataMapItems");
                    // Broadcast DataMap contents to wearable show in notification..
                    if (dataItems != null && dataItems.size() > 0) {
                            for (DataMap item : dataItems) {
                              ........
                            }       
                    }
                }
            }
        }
    }
}

上面的代码工作正常。每当我从 mobileApp 的 MainActivity 发送数据时,我都会在 PhoneListenerService 的 Wear 应用程序上收到它。

///////////////////////////////////////// ///////////////////////////////////////// ///////////////////////////////////////// //////

根据接收到的数据,我在穿戴应用程序上构建通知,并针对我想要通知移动应用程序的通知采取的每项操作。为此,我在 Wear 应用上创建了 PhoneSyncService,它将通知移动应用所采取的行动。

public class PhoneSyncService extends IntentService implements
        GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks{

    private static final String "wearsrvc-w" = "PhoneSyncService-W";

    public static final String ACTION_REPLY = "com.test.mobilewearsample.action.REPLY";

    GoogleApiClient mGoogleClient;

    public PhoneSyncService() {
        super("PhoneSyncService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mGoogleClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }

    @Override
    public void onDestroy() {
        if (null != mGoogleClient && mGoogleClient.isConnected()) {
            mGoogleClient.disconnect();
        }
        super.onDestroy();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            Log.w("wearsrvc-w", "ACTION : "+action);
            if (ACTION_REPLY.equals(action)) {
                final String uId = intent.getStringExtra("dataId");
                notifyHandheldDevice(uId);
            }
        }
    }

    private void notifyHandheldDevice(String uId) {
        Log.v("wearsrvc-w", "in notify to handheld device :"+uId);

        if (mGoogleClient.isConnected()) {
            DataMap dataMap = new DataMap();
            dataMap.putInt("uId", Integer.valueOf(uId));
            PutDataMapRequest putDMR = PutDataMapRequest.create("/mobiledatapath");
            putDMR.getDataMap().putAll(dataMap);
            PutDataRequest request = putDMR.asPutDataRequest();
            DataApi.DataItemResult result = Wearable.DataApi.putDataItem(mGoogleClient, request).await();
            if (result.getStatus().isSuccess()) {
                Log.v("wearsrvc-w" , "Wear DataMap: " + dataMap + " sent successfully to data layer ");
            } else {
                // Log an error
                Log.v("wearsrvc-w" , "ERROR: failed to send DataMap to data layer");
            }
        }
        Log.v("wearsrvc-w", "done notify to handheld device :"+uId);
    }

    @Override
    public void onConnected(Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }
}

为了获取从穿戴应用程序发送到移动应用程序的数据,我还在移动应用程序上创建了 WearDataListenerService,下面是代码。

public class WearDataListenerService  extends WearableListenerService {
    private static final String TAG = "WearDataLstrService-M";


    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {


        for (DataEvent event : dataEvents) {
            Log.v(TAG, "DataMap received on mobile: " + DataMapItem.fromDataItem(event.getDataItem()).getDataMap());
            // Check the data type
            Log.v(TAG, "event type :"+event.getType());
            if (event.getType() == DataEvent.TYPE_CHANGED) {
                // Check the data path
                String path = event.getDataItem().getUri().getPath();
                if (path.equals("/mobiledatapath")) {
                    DataMap dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                    int uId = dataMap.getInt("dataId");
                    Log.v(TAG, "action received for uId :"+uId);
                }

            }
        }
    }

}

当我进行上述更改时,我开始看到一个奇怪的问题。当我尝试将数据从移动应用程序发送到穿戴应用程序时,数据会在WearDataListenerService上接收,该服务仅在移动应用程序端,而不会在穿戴应用程序端接收。 就像从移动应用程序发送的数据是在移动应用程序 WearableListenerService 上接收的,而不是在 Wear 应用程序上接收的。

有人可以帮帮我吗。

4

1 回答 1

1

您的移动侦听器服务具有以下行:

if (path.equals("/mobiledatapath")) {}

我认为您关闭该街区为时过早;你的意思是:

if (path.equals("/mobiledatapath")) {
  // rest of that code
}

您的移动端正在添加/更改数据,因此任何节点都可以接收回调,包括移动设备,这就是您的移动设备接收它的原因(并且由于您的错误 if 子句,它没有被过滤掉)。至于另一部分,您在数据(mDataMapList)中发送的有效负载是什么?多次尝试是同一件事还是每次都改变?有两种可能的原因:

  • 您的有效负载是相同的,因此没有“更改”,因此不会再次调用 onDataChanged (例如,向数据添加时间戳可以解决该问题)
  • 在 Play Services 8.3+ 中,进行了一些更改,以批量跨网络同步数据并且不立即传输它们(最多可以延迟 20 分钟);如果应用程序需要立即同步,他们需要设置紧急标志,请参阅setUrgent()。在移动端,可以立即看到变化(不是跨线),但在磨损端,除非紧急发送,否则可能需要一段时间。
于 2016-01-20T16:20:15.870 回答