blob: ef47977e33980c32b021edfba27c03d55cc27c33 [file] [log] [blame]
/*
* 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.example.android.wearable.agendadata;
import static com.example.android.wearable.agendadata.Constants.TAG;
import static com.example.android.wearable.agendadata.Constants.EXTRA_SILENT;
import static com.example.android.wearable.agendadata.Constants.ALL_DAY;
import static com.example.android.wearable.agendadata.Constants.BEGIN;
import static com.example.android.wearable.agendadata.Constants.DESCRIPTION;
import static com.example.android.wearable.agendadata.Constants.END;
import static com.example.android.wearable.agendadata.Constants.PROFILE_PIC;
import static com.example.android.wearable.agendadata.Constants.TITLE;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.Asset;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataItem;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Listens to DataItem events on the home device.
*/
public class HomeListenerService extends WearableListenerService {
private static final Map<Uri, Integer> sNotificationIdByDataItemUri =
new HashMap<Uri, Integer>();
private static int sNotificationId = 1;
private GoogleApiClient mGoogleApiClient;
@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) {
deleteDataItem(event.getDataItem());
} else if (event.getType() == DataEvent.TYPE_CHANGED) {
UpdateNotificationForDataItem(event.getDataItem());
}
}
dataEvents.close();
}
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this.getApplicationContext())
.addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
}
/**
* Posts a local notification to show calendar card.
*/
private void UpdateNotificationForDataItem(DataItem dataItem) {
DataMapItem mapDataItem = DataMapItem.fromDataItem(dataItem);
DataMap data = mapDataItem.getDataMap();
String description = data.getString(DESCRIPTION);
if (TextUtils.isEmpty(description)) {
description = "";
} else {
// Add a space between the description and the time of the event.
description += " ";
}
String contentText;
if (data.getBoolean(ALL_DAY)) {
contentText = getString(R.string.desc_all_day, description);
} else {
String startTime = DateFormat.getTimeFormat(this).format(new Date(data.getLong(BEGIN)));
String endTime = DateFormat.getTimeFormat(this).format(new Date(data.getLong(END)));
contentText = getString(R.string.desc_time_period, description, startTime, endTime);
}
Intent deleteOperation = new Intent(this, DeleteService.class);
// Use a unique identifier for the delete action.
String deleteAction = "action_delete" + dataItem.getUri().toString() + sNotificationId;
deleteOperation.setAction(deleteAction);
deleteOperation.setData(dataItem.getUri());
PendingIntent deleteIntent = PendingIntent.getService(this, 0, deleteOperation,
PendingIntent.FLAG_ONE_SHOT);
PendingIntent silentDeleteIntent = PendingIntent.getService(this, 1,
deleteOperation.putExtra(EXTRA_SILENT, true), PendingIntent.FLAG_ONE_SHOT);
Notification.Builder notificationBuilder = new Notification.Builder(this)
.setContentTitle(data.getString(TITLE))
.setContentText(contentText)
.setSmallIcon(R.drawable.ic_launcher)
.addAction(R.drawable.ic_menu_delete, getText(R.string.delete), deleteIntent)
.setDeleteIntent(silentDeleteIntent) // Delete DataItem if notification dismissed.
.setLocalOnly(true)
.setPriority(Notification.PRIORITY_MIN);
// Set the event owner's profile picture as the notification background.
Asset asset = data.getAsset(PROFILE_PIC);
if (null != asset) {
if (mGoogleApiClient.isConnected()) {
DataApi.GetFdForAssetResult assetFdResult =
Wearable.DataApi.getFdForAsset(mGoogleApiClient, asset).await();
if (assetFdResult.getStatus().isSuccess()) {
Bitmap profilePic = BitmapFactory.decodeStream(assetFdResult.getInputStream());
notificationBuilder.extend(new Notification.WearableExtender()
.setBackground(profilePic));
} else if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "asset fetch failed with statusCode: "
+ assetFdResult.getStatus().getStatusCode());
}
} else {
Log.e(TAG, "Failed to set notification background"
+ " - Client disconnected from Google Play Services");
}
}
Notification card = notificationBuilder.build();
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.notify(sNotificationId, card);
sNotificationIdByDataItemUri.put(dataItem.getUri(), sNotificationId++);
}
/**
* Deletes the calendar card associated with the data item.
*/
private void deleteDataItem(DataItem dataItem) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "onDataItemDeleted:DataItem=" + dataItem.getUri());
}
Integer notificationId = sNotificationIdByDataItemUri.remove(dataItem.getUri());
if (notificationId != null) {
((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(notificationId);
}
}
@Override
public void onMessageReceived(MessageEvent messageEvent) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onMessageReceived: " + messageEvent.getPath()
+ " " + messageEvent.getData() + " for " + getPackageName());
}
}
}