Проблемы с получением обновлений Wearable Data API

Я повторно использую некоторые классы из демонстрации FindMyPhone для Android Wear https://github.com/mauimauer/AndroidWearable-Samples/tree/master/FindMyPhone

Я пытаюсь отправить сообщение в портативное приложение, но только после того, как пользователь нажмет кнопку запуска на своих часах 5 раз. Если я установлю для триггера значение true для первого запуска, он сработает. Но когда я использую счетчик для установки триггера true после 5 запусков, я вижу вывод журнала

package com.mayday.md;

import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.DataItemBuffer;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.Wearable;

import java.util.concurrent.TimeUnit;

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

    private static final String TAG = "ExampleFindPhoneApp";

    private static final String FIELD_ALARM_ON = "alarm_on";
    private static final String PATH_SOUND_ALARM = "/sound_alarm";
    public static final String ACTION_TOGGLE_ALARM = "action_toggle_alarm";
    public static final String ACTION_CANCEL_ALARM = "action_alarm_off";

    // Timeout for making a connection to GoogleApiClient (in milliseconds).
    private static final long CONNECTION_TIME_OUT_MS = 100;
    private GoogleApiClient mGoogleApiClient;

    public FindPhoneService() {
        super(FindPhoneService.class.getSimpleName());
    }

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

    @Override
    protected void onHandleIntent(Intent intent) {
        SharedPreferences mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        int c = mPref.getInt("numRun", 0);
        int TIME_INTERVAL = 10000;
        int TOTAL_CLICKS = 5;
        long delta = 0;
        Long eventTime = System.currentTimeMillis();
        boolean trigger = false;
        mPref.edit().putLong("eventTime", eventTime).commit();
        Long firstEventTime = mPref.getLong("firstEventTime", 0);
        if (firstEventTime == 0) {
            firstEventTime = eventTime;
            mPref.edit().putLong("firstEventTime", firstEventTime).commit();
        }
        delta = eventTime - firstEventTime;
        Log.e(">>>>>>", "START_BY_WEAR delta " + delta);
        if (delta < TIME_INTERVAL) {
            c++;
            mPref.edit().putInt("numRun",c).commit();
            Log.e(">>>>>>", "START_BY_WEAR "+c);
            if (c >=TOTAL_CLICKS) {
                Log.e(">>>>>>", "START_BY_WEAR TRIGGER START");
                mPref.edit().putInt("numRun", 0).commit();
                mPref.edit().putLong("firstEventTime", 0).commit();
                trigger = true;
                Log.e(">>>>>>", "START_BY_WEAR TRIGGER END");

            }
        } else {
            mPref.edit().putInt("numRun", 0).commit();
            mPref.edit().putLong("firstEventTime", 0).commit();
        }
        if (trigger) {
            mGoogleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "FindPhoneService.onHandleIntent");
            }
            if (mGoogleApiClient.isConnected()) {
                // Set the alarm off by default.
                boolean alarmOn = false;
                if (intent.getAction().equals(ACTION_TOGGLE_ALARM)) {
                    // Get current state of the alarm.
                    DataItemBuffer result = Wearable.DataApi.getDataItems(mGoogleApiClient).await();
                    Log.v(TAG, "DataItemBuffer result " + result);
                    if (result.getStatus().isSuccess()) {
                        if (result.getCount() == 1) {
                            alarmOn = DataMap.fromByteArray(result.get(0).getData())
                                    .getBoolean(FIELD_ALARM_ON, false);
                        } else {
                            Log.e(TAG, "Unexpected number of DataItems found.\n"
                                    + "\tExpected: 1\n"
                                    + "\tActual: " + result.getCount());
                        }
                    } else if (Log.isLoggable(TAG, Log.DEBUG)) {
                        Log.d(TAG, "onHandleIntent: failed to get current alarm state");
                    }
                    result.close();
                    // Toggle alarm.
                    alarmOn = !alarmOn;
                    // Change notification text based on new value of alarmOn.
                    String notificationText = alarmOn ? getString(R.string.turn_alarm_off)
                            : getString(R.string.turn_alarm_on);
                    Log.e(">>>>>>", "FindPhoneService notificationText " + notificationText);
                    FindPhoneActivity.updateNotification(this, notificationText);
                }
                // Use alarmOn boolean to update the DataItem - phone will respond accordingly
                // when it receives the change.
                Log.e(">>>>>>", "FindPhoneService putDataItem");
                PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(PATH_SOUND_ALARM);
                putDataMapRequest.getDataMap().putBoolean(FIELD_ALARM_ON, alarmOn);
                Wearable.DataApi.putDataItem(mGoogleApiClient, putDataMapRequest.asPutDataRequest())
                        .await();
                Log.e(">>>>>>", "FindPhoneService end putDataItem");

            } else {
                Log.e(TAG, "Failed to toggle alarm on phone - Client disconnected from Google Play "
                        + "Services");
            }
            mGoogleApiClient.disconnect();
        }
    }


}

Он запускает строку Wearable.DataApi.putDataItem(mGoogleApiClient, putDataMapRequest.asPutDataRequest()).await(); без ошибок. Это логарифм для носимых устройств.

02-20 10:44:23.098  20683-20683/com.mayday.md I/art﹕ Late-enabling -Xcheck:jni
02-20 10:44:23.351  20683-20683/com.mayday.md E/>>>>>>﹕ FindPhoneActivity onCreate
02-20 10:44:23.359  20683-20683/com.mayday.md E/>>>>>>﹕ FindPhoneActivity onCreate
02-20 10:44:23.363  20683-20683/com.mayday.md E/>>>>>>﹕ FindPhoneActivity onCreate
02-20 10:44:23.599  20683-20695/com.mayday.md I/art﹕ Background sticky concurrent mark sweep GC freed 1734(89KB) AllocSpace objects, 0(0B) LOS objects, 29% free, 467KB/667KB, paused 2.716ms total 134.918ms
02-20 10:58:30.536  20683-20718/com.mayday.md E/>>>>>>﹕ START_BY_WEAR delta 0
02-20 10:58:30.548  20683-20718/com.mayday.md E/>>>>>>﹕ START_BY_WEAR 1
02-20 10:58:32.529  20683-20720/com.mayday.md E/>>>>>>﹕ START_BY_WEAR delta 2008
02-20 10:58:32.542  20683-20720/com.mayday.md E/>>>>>>﹕ START_BY_WEAR 2
02-20 10:58:33.530  20683-20721/com.mayday.md E/>>>>>>﹕ START_BY_WEAR delta 3009
02-20 10:58:33.543  20683-20721/com.mayday.md E/>>>>>>﹕ START_BY_WEAR 3
02-20 10:58:34.578  20683-20722/com.mayday.md E/>>>>>>﹕ START_BY_WEAR delta 4058
02-20 10:58:34.591  20683-20722/com.mayday.md E/>>>>>>﹕ START_BY_WEAR 4
02-20 10:58:35.499  20683-20723/com.mayday.md E/>>>>>>﹕ START_BY_WEAR delta 4980
02-20 10:58:35.520  20683-20723/com.mayday.md E/>>>>>>﹕ START_BY_WEAR 5
02-20 10:58:35.521  20683-20723/com.mayday.md E/>>>>>>﹕ START_BY_WEAR TRIGGER START
02-20 10:58:35.541  20683-20723/com.mayday.md E/>>>>>>﹕ START_BY_WEAR TRIGGER END
02-20 10:58:35.629  20683-20723/com.mayday.md V/ExampleFindPhoneApp﹕ DataItemBuffer result com.google.android.gms.wearable.DataItemBuffer@2cb077a4
02-20 10:58:35.630  20683-20723/com.mayday.md E/ExampleFindPhoneApp﹕ Unexpected number of DataItems found.
    Expected: 1
    Actual: 3
02-20 10:58:35.630  20683-20723/com.mayday.md E/>>>>>>﹕ FindPhoneService notificationText Tap 5x for MayDay alert.
02-20 10:58:35.630  20683-20723/com.mayday.md E/>>>>>>﹕ FindPhoneActivity notification com.mayday.md.FindPhoneService@623de6a
02-20 10:58:35.631  20683-20723/com.mayday.md E/>>>>>>﹕ FindPhoneActivity notification Tap 5x for MayDay alert.
02-20 10:58:35.668  20683-20723/com.mayday.md E/>>>>>>﹕ FindPhoneService putDataItem
02-20 10:58:35.703  20683-20723/com.mayday.md E/>>>>>>﹕ FindPhoneService end putDataItem

SoundAlarmListenerService не видит обновления

package com.mayday.md.trigger;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.util.Log;

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

import java.io.IOException;

/**
 * Listens for disconnection from home device.
 */
public class SoundAlarmListenerService extends WearableListenerService {

    HardwareTriggerReceiver hardwareTriggerReceiver = new HardwareTriggerReceiver();

    private static final String TAG = "ExampleFindPhoneApp";

    private static final String FIELD_ALARM_ON = "alarm_on";

    private AudioManager mAudioManager;
    private static int mOrigVolume;
    private int mMaxVolume;
    private Uri mAlarmSound;
    private MediaPlayer mMediaPlayer;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "ExampleFindPhoneApp SoundAlarmListenerService Created");
        hardwareTriggerReceiver.onActivation(getApplicationContext());

/*
        Log.d(TAG, "ExampleFindPhoneApp ran trigger");
        mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        mOrigVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
        mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
        mAlarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        mMediaPlayer = new MediaPlayer();
*/
    }

    @Override
    public void onDestroy() {
        // Reset the alarm volume to the user's original setting.
        //mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mOrigVolume, 0);
        //mMediaPlayer.release();
        super.onDestroy();
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: " + dataEvents + " for " + getPackageName());
        }
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_DELETED) {
                Log.i(TAG, event + " deleted");
            } else if (event.getType() == DataEvent.TYPE_CHANGED) {
                Boolean alarmOn =
                        DataMap.fromByteArray(event.getDataItem().getData()).get(FIELD_ALARM_ON);
                if (alarmOn) {
                    /*
                    mOrigVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
                    mMediaPlayer.reset();
                    // Sound alarm at max volume.
                    mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mMaxVolume, 0);
                    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
                    try {
                        mMediaPlayer.setDataSource(getApplicationContext(), mAlarmSound);
                        mMediaPlayer.prepare();
                    } catch (IOException e) {
                        Log.e(TAG, "Failed to prepare media player to play alarm.", e);
                    }
                    mMediaPlayer.start();
                    */
                } else {
                    // Reset the alarm volume to the user's original setting.
                    /*
                    mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mOrigVolume, 0);
                    if (mMediaPlayer.isPlaying()) {
                        mMediaPlayer.stop();
                    }
                    */
                }
            }
        }
        dataEvents.close();
    }

}

ОБНОВЛЕНИЕ

Я думаю, проблема в том, что слушатель ищет обновление карты данных, но обновления не происходит. Так может запустить обновление? Может быть, добавить поле метки времени?


person Jack Shultz    schedule 20.02.2015    source источник


Ответы (1)


Я думаю, что это полезное решение для следующего человека, пытающегося отправить обновления на Wearable.DataApi.putDataItem. Теперь я понимаю, что приемник срабатывает только при изменении данных. Если все, что вы отправляете, является логическим значением, которое никогда не меняется, вам нужно добавить другое значение, которое действительно меняется. Поэтому я добавил метку времени, которая теперь запускает приемник.

        PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(PATH_SOUND_ALARM);
        putDataMapRequest.getDataMap().putBoolean(FIELD_ALARM_ON, alarmOn);
        putDataMapRequest.getDataMap().putLong(ACTION_TIME_STAMP, System.currentTimeMillis());

        if (triggerCounter(putDataMapRequest)) {
            Log.d(TAG, "onHandleIntent: putDataMapRequest " + putDataMapRequest.toString());
            Wearable.DataApi.putDataItem(mGoogleApiClient, putDataMapRequest.asPutDataRequest()).await();
            //triggerCounter(putDataMapRequest);
        }
person Jack Shultz    schedule 20.02.2015