com.onecase.chatroom.service.DataLayerService.java Source code

Java tutorial

Introduction

Here is the source code for com.onecase.chatroom.service.DataLayerService.java

Source

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.onecase.chatroom.service;

import java.util.List;
import java.util.concurrent.TimeUnit;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.Uri;
import android.os.Looper;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.data.FreezableUtils;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;
import com.google.android.gms.wearable.DataApi.DataItemResult;
import com.onecase.chatroom.R;
import com.onecase.chatroom.event.SendDataEvent;
import com.onecase.chatroom.model.NotificationData;
import com.onecase.chatroom.ui.ChatroomUI;
import com.onecase.chatroom.ui.FitnessUI;
import com.onecase.chatroom.ui.MessageListUI;
import com.onecase.chatroom.util.ChatroomConstants;
import com.onecase.sdk.Util;
import com.onecase.sdk.event.BaseEvent;
import com.onecase.sdk.event.BaseEventListener;
import com.onecase.sdk.event.EventCenter;
import com.onecase.sdk.handler.OCHandler;
import com.onecase.sdk.log.Log;

/**
 * Listens to DataItems and Messages from the local node.
 */
public class DataLayerService extends WearableListenerService {
    private static final String TAG = "Onecase.Wear.DataLayerService";
    private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";

    private GoogleApiClient googleApiClient;
    private OCHandler sendDataHandler;

    private void startSendThread() {
        Thread t = new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                sendDataHandler = new OCHandler(Looper.myLooper());
                Looper.loop();
            }
        };
        t.setPriority(Thread.MIN_PRIORITY);
        t.start();
        while (sendDataHandler == null)
            ;
    }

    private void stopSendThread() {
        if (sendDataHandler != null) {
            sendDataHandler.removeCallbacksAndMessages(null);
            sendDataHandler.getLooper().quit();
            sendDataHandler = null;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "Create DataLayerService");
        EventCenter.getEventPool().addListener(SendDataEvent.ID, sendDataEventListener);
        googleApiClient = new GoogleApiClient.Builder(this).addApi(Wearable.API).build();
        googleApiClient.connect();
        startSendThread();
    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "Destory DataLayerService");
        EventCenter.getEventPool().removeListener(SendDataEvent.ID, sendDataEventListener);
        googleApiClient.disconnect();
        stopSendThread();
        super.onDestroy();
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        Log.d(TAG, "onDataChanged(): %s", dataEvents.toString());
        final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
        dataEvents.close();
        if (!googleApiClient.isConnected()) {
            ConnectionResult connectionResult = googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
            if (!connectionResult.isSuccess()) {
                Log.e(TAG, "DataLayerListenerService failed to connect to GoogleApiClient.");
                return;
            }
        }

        // Loop through the events and send a message back to the node that created the data item.
        for (DataEvent event : events) {
            Log.d(TAG, "event: %s", Util.notNullToString(event));
            handleDataEvent(event);
        }
    }

    private void handleDataEvent(DataEvent event) {
        String path = event.getDataItem().getUri().getPath();
        Log.d(TAG, "handleDataEvent path=%s", path);
        if (path.equals(ChatroomConstants.DataLayer.HEART_BIT_PATH)) {
            Uri uri = event.getDataItem().getUri();
            String nodeId = uri.getHost();
            byte[] payload = uri.toString().getBytes();
            if (sendDataHandler != null) {
                sendDataHandler.post(new SendMessageTask(nodeId, payload));
            }
        } else if (path.startsWith(ChatroomConstants.DataLayer.DATA_PHAT_PREFIX)) {
            DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
            String dataString = new String(
                    dataMapItem.getDataMap().getByteArray(ChatroomConstants.DataLayer.KEY_DATA));
            Log.d(TAG, "handleDataEvent dataString=%s", dataString);
            if (path.equals(ChatroomConstants.DataLayer.NOTIFICATION_PATH)) {
                NotificationData notificationData = Util.toJSONObject(dataString, NotificationData.class);
                notify(notificationData);
            }
        }
    }

    private void notify(NotificationData notificationData) {
        int notificationId = 001;
        Intent firstPageIntent = new Intent(this, FitnessUI.class);
        PendingIntent firstPagePendingIntent = PendingIntent.getActivity(this, 0, firstPageIntent, 0);
        NotificationCompat.Builder firstPageBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher).setContentTitle(notificationData.title)
                .setContentText(notificationData.content).setContentIntent(firstPagePendingIntent)
                .setLocalOnly(true);

        Intent secondPageIntent = new Intent(this, MessageListUI.class);
        PendingIntent secondPagePendingIntent = PendingIntent.getActivity(this, 0, secondPageIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        Notification secondPageNotification = new NotificationCompat.Builder(this)
                .extend(new NotificationCompat.WearableExtender().setDisplayIntent(secondPagePendingIntent)
                        .setCustomSizePreset(Notification.WearableExtender.SIZE_MEDIUM))
                .build();
        Notification notification = new NotificationCompat.WearableExtender().addPage(secondPageNotification)
                .extend(firstPageBuilder).build();

        NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);
        notificationManagerCompat.notify(notificationId++, notification);
    }

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        Log.d(TAG, "onMessageReceived: %s", Util.notNullToString(messageEvent));
        // Check to see if the message is to start an activity
        if (messageEvent.getPath().equals(ChatroomConstants.StartActivity.START_FITNESS_PATH)) {
            Intent startIntent = new Intent(this, FitnessUI.class);
            startIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(startIntent);
        }
        if (messageEvent.getPath().equals(ChatroomConstants.StartActivity.START_CHATROOM_PATH)) {
            Intent startIntent = new Intent(this, ChatroomUI.class);
            startIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(startIntent);
        }
    }

    public void onPeerConnected(Node peer) {
        Log.i(TAG, "onPeerConnected: %s", Util.notNullToString(peer));
    }

    public void onPeerDisconnected(Node peer) {
        Log.i(TAG, "onPeerDisconnected: %s", Util.notNullToString(peer));
    }

    private BaseEventListener sendDataEventListener = new BaseEventListener(0) {
        @Override
        public boolean callback(BaseEvent baseEvent) {
            if (baseEvent instanceof SendDataEvent) {
                SendDataEvent sendDataEvent = (SendDataEvent) baseEvent;
                Log.d(TAG, "sendDataEvent, path=%s", sendDataEvent.path);
                PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(sendDataEvent.path);
                putDataMapRequest.getDataMap().putByteArray(ChatroomConstants.DataLayer.KEY_DATA,
                        sendDataEvent.data);
                PutDataRequest request = putDataMapRequest.asPutDataRequest();
                Log.d(TAG, "Generating DataItem: %s", Util.notNullToString(request));
                if (!googleApiClient.isConnected()) {
                    return false;
                }
                if (sendDataHandler != null) {
                    sendDataHandler.post(new SendDataTask(request));
                }
            }
            return false;
        }
    };

    private class SendDataTask implements Runnable {
        private PutDataRequest request;

        public SendDataTask(PutDataRequest request) {
            this.request = request;
        }

        @Override
        public void run() {
            Wearable.DataApi.putDataItem(googleApiClient, request)
                    .setResultCallback(new ResultCallback<DataItemResult>() {
                        @Override
                        public void onResult(DataItemResult dataItemResult) {
                            if (!dataItemResult.getStatus().isSuccess()) {
                                Log.e(TAG, "ERROR: failed to putDataItem, status code: %d",
                                        dataItemResult.getStatus().getStatusCode());
                            }
                        }
                    });
        }
    }

    private class SendMessageTask implements Runnable {

        private String nodeId;
        private byte[] payload;

        public SendMessageTask(String nodeId, byte[] payload) {
            this.nodeId = nodeId;
            this.payload = payload;
        }

        @Override
        public void run() {
            Wearable.MessageApi.sendMessage(googleApiClient, nodeId, DATA_ITEM_RECEIVED_PATH, payload);
        }

    }
}