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