0

着用するデータを送信するアクティビティを使用してモバイル アプリを作成しました。モバイルアプリ側のコードは次のとおりです

行数を減らすために一部のコードを削除したことに注意してください。

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) {
                              ........
                            }       
                    }
                }
            }
        }
    }
}

上記のコードは正常に動作します。MainActivity から mobileApp からデータを送信するたびに、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) {

    }
}

Wear アプリからモバイル アプリに送信されたデータを取得するために、モバイル アプリでも 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 で受信されるようです。

誰か助けてください。

4

1 に答える 1

1

モバイル リスナー サービスには次の行があります。

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

ブロックを閉じるのが早すぎると思います。するつもりでしたか:

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

モバイル側でデータを追加/変更しているため、モバイルデバイスを含む任意のノードがコールバックを受信できるため、モバイル デバイスがそれを受信します (if 節が間違っているため、除外されません)。他の部分については、データ (mDataMapList) で送信しているペイロードは何ですか? それは複数の試行で同じことですか、それとも毎回変化しますか? 次の 2 つの原因が考えられます。

  • ペイロードは同じであるため、「変更」がないため、 onDataChanged が再度呼び出されることはありません (たとえば、データにタイムスタンプを追加すると、それに対処できます)
  • Play サービス 8.3 以降では、ネットワーク全体でデータ同期をバッチ処理し、すぐにではなく転送するようにいくつかの変更が行われました (最大 20 分遅れる可能性があります)。アプリがすぐに同期する必要がある場合は、緊急フラグを設定する必要があります。 setUrgent()を参照してください。モバイル側では、変更はすぐに確認できますが (クロス ワイヤではありません)、摩耗側では、緊急として送信しない限り、しばらく時間がかかる場合があります。
于 2016-01-20T16:20:15.870 に答える