Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Wear sending data to Android phone, but phone appears to never receive it

Short Summary: I am attempting to send data from an Android Wear watch to an Android phone using PutDataRequest and GoogleApiClient. Logs seem to show the data is sent successfully, but onDataChanged never fires. I am using Android Studio 1.0.2. I am not using any emulator but an Android Wear watch I own--which I have paired and enabled debugging via the Android Wear device and the Android Wear application on the phone. On both the phone and wear's AndroidManifest.xml, I include com.google.android.gms.version.

On the Android Phone (4.4.4 version of Android), I use a listener service, which is bound via the AndroidManifest.xml and started via the main activity on the phone. From logs, I can confirm the service is successfully created on the phone but no data is ever received (onDataChanged never fires -- to be precise).

    <!-- Phone manifest, registers the listener -->
    <service android:name=".DataLayerListenerService" >
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
        </intent-filter>
    </service>

Here is the listener service, which runs on the phone:

public class DataLayerListenerService extends WearableListenerService {
    private static final String TAG = DataLayerListenerService.class.getName();
    private GoogleApiClient mGoogleApiClient;

    private static final String WEARABLE_DATA_PATH = "/audio";

    @Override
    public void onCreate() {
        // I can see this fires properly on the Android mobile phone
        Logger.d(TAG, "onCreate");
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        // This never fires on the Android mobile phone, even though Wear says data was sent successfully
        Logger.d(TAG, "on change");
    }
}

On the Wear device, I have a main activity that creates a Google API client. I use a UI button to generate input from audio (code not shown), which I know is working right because of logging. I then attempt to send this data from the wear device to the phone. In the logs, I see "result available. Status: Status{statusCode=SUCCESS, resolution=null}" (I use a result callback to track).

public class MainActivity extends Activity implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {
    private static final String TAG = MainActivity.class.getName();
    private static final int SPEECH_REQUEST_CODE = 1;

    private static final int RECORDER_SAMPLERATE = 44100;
    private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
    private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

    private TextView mTextView;
    private AudioRecord recorder;
    private int bufferSize = 0;
    private Thread recordingThread = null;
    private GoogleApiClient mGoogleApiClient;
    private volatile boolean isRecording;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "Creating MainActivity");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                mTextView = (TextView) stub.findViewById(R.id.text);
            }
        });

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }

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

    protected void onResume() {
        if (null != mGoogleApiClient && !mGoogleApiClient.isConnected()) {
            mGoogleApiClient.connect();
        }
        super.onResume();
    }

    @Override
    protected void onStop() {
        if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
        super.onStop();
    }

    // Placeholders for required connection callbacks
    @Override
    public void onConnectionSuspended(int cause) {
        Log.d(TAG, "Connection suspended");
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.d(TAG, "Connection failed");
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        Log.d(TAG, "Connected successfully");
    }

    // This is invoked from the UI, via a helper method not shown. Logs show the method is invoked fine.
    private void processRawAudioData() {
        byte data[] = new byte[bufferSize];
        int read = 0;
        while(isRecording) {
            read = recorder.read(data, 0, bufferSize);

            if(AudioRecord.ERROR_INVALID_OPERATION != read) {
                Log.d(TAG, "Successfully read " + data.length + " bytes of audio");
                Log.d(TAG, "Initial ten bytes: " + data[0] + data[1] + data[2] + data[3]
                    + data[4] + data[5] + data[6] + data[7] + data[8] + data[9] + data[10]);

                Asset myAsset = Asset.createFromBytes(data);
                PutDataRequest request = PutDataRequest.create("/audio");
                // might need to change time each time for other end to see change.
                request.putAsset("profileImage", myAsset);
                PendingResult<DataApi.DataItemResult> result =
                    Wearable.DataApi.putDataItem(mGoogleApiClient, request);
                result.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
                    @Override
                    public void onResult(DataApi.DataItemResult dataItemResult) {
                     // LOGS SHOW STATUS "MainActivity﹕ result available. Status: Status{statusCode=SUCCESS, resolution=null}"   
                     Log.d(TAG, "result available. Status: " + dataItemResult.getStatus());
                    }
                });
            }
        }
    }
}
like image 979
eb80 Avatar asked Jan 19 '15 22:01

eb80


Video Answer


1 Answers

In order for the WearableListenerService to fire the 'onDataChanged' event, the applicationId's in the main app and wearable app must match (build.gradle files).

In addition, you cannot send static data, the data must change. That means data in your PutDataMapRequest object must be changing.

like image 147
Steven McWhorter Avatar answered Nov 14 '22 22:11

Steven McWhorter