当两个应用程序都实现WearableListenerService时,无法从移动应用程序发送数据以供应用

时间:2016-01-20 15:50:07

标签: android wear-os android-wear-data-api android-wear-notification

我创建了一个带有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应用程序上构建通知,并对我想要通知移动应用程序的通知采取的每个操作。为此,我在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上收到,而不是在应用程序上收到。

有人可以帮帮我吗。

1 个答案:

答案 0 :(得分:1)

您的移动侦听器服务包含以下行:

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

我认为你过早关闭了这个区块;你的意思是:

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

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

  • 您的有效负载是相同的,因此没有&#34;更改&#34;因此第二次不会调用onDataChanged(例如,添加数据的时间戳可以解决该问题)
  • 在Play Services 8.3+中,对网络上的数据同步进行了一些更改,并且没有立即传输(可以延迟最多20分钟);如果应用需要立即同步,则需要设置紧急标记,请参阅setUrgent()。在移动方面,可以立即看到变化(它不是交叉线),但在磨损方面,它可能需要一段时间,除非发送紧急。