1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.wearable.elizachat;
18 
19 import android.app.Notification;
20 import android.app.PendingIntent;
21 import android.app.Service;
22 import android.content.Intent;
23 import android.graphics.BitmapFactory;
24 import android.os.Bundle;
25 import android.os.IBinder;
26 import android.support.v4.app.NotificationCompat;
27 import android.support.v4.app.RemoteInput;
28 import android.support.v4.content.LocalBroadcastManager;
29 import android.support.v4.app.NotificationManagerCompat;
30 import android.text.TextUtils;
31 import android.util.Log;
32 
33 /**
34  * A service that runs in the background and provides responses to the incoming messages from the
35  * wearable. It also keeps a record of the chat session history, which it can provide upon request.
36  */
37 public class ResponderService extends Service {
38 
39     public static final String ACTION_INCOMING = "com.example.android.wearable.elizachat.INCOMING";
40 
41     public static final String ACTION_RESPONSE = "com.example.android.wearable.elizachat.REPLY";
42 
43     public static final String EXTRA_REPLY = "reply";
44 
45     private static final String TAG = "ResponderService";
46 
47     private ElizaResponder mResponder;
48 
49     private String mLastResponse = null;
50 
51     private StringBuffer mCompleteConversation = new StringBuffer();
52 
53     private LocalBroadcastManager mBroadcastManager;
54 
55     @Override
onCreate()56     public void onCreate() {
57         super.onCreate();
58         if (Log.isLoggable(TAG, Log.DEBUG)) {
59             Log.d(TAG, "Chat Service started");
60         }
61         mResponder = new ElizaResponder();
62         mBroadcastManager = LocalBroadcastManager.getInstance(this);
63         processIncoming(null);
64     }
65 
66     @Override
onBind(Intent intent)67     public IBinder onBind(Intent intent) {
68         return null;
69     }
70 
71     @Override
onStartCommand(Intent intent, int flags, int startId)72     public int onStartCommand(Intent intent, int flags, int startId) {
73         if (null == intent || null == intent.getAction()) {
74             return Service.START_STICKY;
75         }
76         String action = intent.getAction();
77         if (action.equals(ACTION_RESPONSE)) {
78             Bundle remoteInputResults = RemoteInput.getResultsFromIntent(intent);
79             CharSequence replyMessage = "";
80             if (remoteInputResults != null) {
81                 replyMessage = remoteInputResults.getCharSequence(EXTRA_REPLY);
82             }
83             processIncoming(replyMessage.toString());
84         } else if (action.equals(MainActivity.ACTION_GET_CONVERSATION)) {
85             broadcastMessage(mCompleteConversation.toString());
86         }
87         return Service.START_STICKY;
88     }
89 
showNotification()90     private void showNotification() {
91         if (Log.isLoggable(TAG, Log.DEBUG)) {
92             Log.d(TAG, "Sent: " + mLastResponse);
93         }
94         NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
95                 .setContentTitle(getString(R.string.eliza))
96                 .setContentText(mLastResponse)
97                 .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.bg_eliza))
98                 .setSmallIcon(R.drawable.bg_eliza)
99                 .setPriority(NotificationCompat.PRIORITY_DEFAULT);
100 
101         Intent intent = new Intent(ACTION_RESPONSE);
102         PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent,
103                 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT);
104         Notification notification = builder
105                 .extend(new NotificationCompat.WearableExtender()
106                         .addAction(new NotificationCompat.Action.Builder(
107                                 R.drawable.ic_full_reply, getString(R.string.reply), pendingIntent)
108                                 .addRemoteInput(new RemoteInput.Builder(EXTRA_REPLY)
109                                         .setLabel(getString(R.string.reply))
110                                         .build())
111                                 .build()))
112                 .build();
113         NotificationManagerCompat.from(this).notify(0, notification);
114     }
115 
processIncoming(String text)116     private void processIncoming(String text) {
117         if (Log.isLoggable(TAG, Log.DEBUG)) {
118             Log.d(TAG, "Received: " + text);
119         }
120         mLastResponse = mResponder.elzTalk(text);
121         String line = TextUtils.isEmpty(text) ? mLastResponse : text + "\n" + mLastResponse;
122 
123         // Send a new line of conversation to update the Activity, unless the incoming text was
124         // empty.
125         if (!TextUtils.isEmpty(text)) {
126             broadcastMessage(line);
127         }
128         NotificationManagerCompat.from(this).cancelAll();
129         showNotification();
130         mCompleteConversation.append("\n" + line);
131     }
132 
broadcastMessage(String message)133     private void broadcastMessage(String message) {
134         Intent intent = new Intent(MainActivity.ACTION_NOTIFY);
135         intent.putExtra(MainActivity.EXTRA_MESSAGE, message);
136         mBroadcastManager.sendBroadcast(intent);
137     }
138 
139     @Override
onDestroy()140     public void onDestroy() {
141         if (Log.isLoggable(TAG, Log.DEBUG)) {
142             Log.d(TAG, "Chat Service stopped");
143         }
144         NotificationManagerCompat.from(this).cancel(0);
145         mBroadcastManager = null;
146         super.onDestroy();
147     }
148 }
149