/* WearNotificationProfile.java Copyright (c) 2014 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.deviceplugin.wear.profile; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationManagerCompat; import org.deviceconnect.android.deviceplugin.wear.R; import org.deviceconnect.android.event.Event; import org.deviceconnect.android.event.EventError; import org.deviceconnect.android.event.EventManager; import org.deviceconnect.android.message.DConnectMessageService; import org.deviceconnect.android.message.MessageUtils; import org.deviceconnect.android.profile.NotificationProfile; import org.deviceconnect.android.profile.api.DConnectApi; import org.deviceconnect.android.profile.api.DeleteApi; import org.deviceconnect.android.profile.api.PostApi; import org.deviceconnect.android.profile.api.PutApi; import org.deviceconnect.message.DConnectMessage; import org.deviceconnect.message.intent.message.IntentDConnectMessage; import java.util.List; import java.util.Random; /** * Notification Profile. * * @author NTT DOCOMO, INC. */ public class WearNotificationProfile extends NotificationProfile { /** * ランダムを生成するクラス. */ private final Random mRandom = new Random(System.currentTimeMillis()); public WearNotificationProfile() { addApi(mPostNotify); addApi(mDeleteNotify); addApi(mDeleteOnClick); addApi(mPutOnClick); addApi(mDeleteOnClose); addApi(mPutOnClose); addApi(mDeleteOnShow); addApi(mPutOnShow); } private final DConnectApi mPostNotify = new PostApi() { @Override public String getAttribute() { return ATTRIBUTE_NOTIFY; } @Override public boolean onRequest(final Intent request, final Intent response) { final String serviceId = getServiceID(request); final NotificationType type = getType(request); final String body = getBody(request); Bitmap myBitmap; Resources myRes = getContext().getResources(); NotificationCompat.Builder myNotificationBuilder; NotificationManagerCompat myNotificationManager; int myNotificationId = mRandom.nextInt(Integer.MAX_VALUE); Intent clickIntent = new Intent(getContext(), org.deviceconnect.android.deviceplugin.wear.WearDeviceService.class); clickIntent.setAction(WearConst.DEVICE_TO_WEAR_NOTIFICATION_OPEN); clickIntent.putExtra(WearConst.PARAM_DEVICEID, serviceId); clickIntent.putExtra(WearConst.PARAM_NOTIFICATIONID, myNotificationId); PendingIntent clickPendingIntent = PendingIntent.getService(getContext(), 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT); Intent deleteIntent = new Intent(getContext(), org.deviceconnect.android.deviceplugin.wear.WearDeviceService.class); deleteIntent.setAction(WearConst.DEVICE_TO_WEAR_NOTIFICATION_CLOSED); deleteIntent.putExtra(WearConst.PARAM_DEVICEID, serviceId); deleteIntent.putExtra(WearConst.PARAM_NOTIFICATIONID, myNotificationId); PendingIntent deletePendingIntent = PendingIntent.getService(getContext(), 0, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT); switch (type) { case PHONE: myBitmap = BitmapFactory.decodeResource(myRes, R.drawable.notification_00); myNotificationBuilder = new NotificationCompat.Builder(getContext()) .setSmallIcon(R.drawable.notification_00).setContentTitle("Phone").setContentText(body) .setContentIntent(clickPendingIntent).setLargeIcon(myBitmap) .setVibrate(new long[]{500}).setDeleteIntent(deletePendingIntent) .setWhen(System.currentTimeMillis()) .extend(new NotificationCompat.WearableExtender()); break; case MAIL: myBitmap = BitmapFactory.decodeResource(myRes, R.drawable.notification_01); myNotificationBuilder = new NotificationCompat.Builder(getContext()) .setSmallIcon(R.drawable.notification_01).setContentTitle("Mail").setContentText(body) .setContentIntent(clickPendingIntent).setLargeIcon(myBitmap) .setVibrate(new long[]{500}).setDeleteIntent(deletePendingIntent) .setWhen(System.currentTimeMillis()) .extend(new NotificationCompat.WearableExtender()); break; case SMS: myBitmap = BitmapFactory.decodeResource(myRes, R.drawable.notification_02); myNotificationBuilder = new NotificationCompat.Builder(getContext()) .setSmallIcon(R.drawable.notification_02).setContentTitle("SMS").setContentText(body) .setContentIntent(clickPendingIntent).setLargeIcon(myBitmap) .setVibrate(new long[]{500}).setDeleteIntent(deletePendingIntent) .setWhen(System.currentTimeMillis()) .extend(new NotificationCompat.WearableExtender()); break; case EVENT: myBitmap = BitmapFactory.decodeResource(myRes, R.drawable.notification_03); myNotificationBuilder = new NotificationCompat.Builder(getContext()) .setSmallIcon(R.drawable.notification_03).setContentTitle("Event").setContentText(body) .setContentIntent(clickPendingIntent).setLargeIcon(myBitmap) .setVibrate(new long[]{500}).setDeleteIntent(deletePendingIntent) .setWhen(System.currentTimeMillis()) .extend(new NotificationCompat.WearableExtender()); break; case UNKNOWN: default: MessageUtils.setInvalidRequestParameterError(response); return true; } // Send Notification. myNotificationManager = NotificationManagerCompat.from(getContext()); myNotificationManager.notify(myNotificationId, myNotificationBuilder.build()); response.putExtra(NotificationProfile.PARAM_NOTIFICATION_ID, myNotificationId); setResult(response, IntentDConnectMessage.RESULT_OK); List<Event> events = EventManager.INSTANCE.getEventList(serviceId, WearNotificationProfile.PROFILE_NAME, null, WearNotificationProfile.ATTRIBUTE_ON_SHOW); synchronized (events) { for (Event event : events) { Intent msg = EventManager.createEventMessage(event); msg.putExtra(WearNotificationProfile.PARAM_NOTIFICATION_ID, myNotificationId); ((DConnectMessageService) getContext()).sendEvent(msg, event.getAccessToken()); } } return true; } }; private final DConnectApi mDeleteNotify = new DeleteApi() { @Override public String getAttribute() { return ATTRIBUTE_NOTIFY; } @Override public boolean onRequest(final Intent request, final Intent response) { NotificationManager manager = (NotificationManager) getContext() .getSystemService(Context.NOTIFICATION_SERVICE); try { manager.cancel(Integer.parseInt(getNotificationId(request))); setResult(response, DConnectMessage.RESULT_OK); } catch (NumberFormatException e) { MessageUtils.setInvalidRequestParameterError(response, "notificationId is invalid."); } return true; } }; private final DConnectApi mDeleteOnClick = new DeleteApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_CLICK; } @Override public boolean onRequest(final Intent request, final Intent response) { return unregisterEvent(request, response, getServiceID(request), getSessionKey(request)); } }; private final DConnectApi mPutOnClick = new PutApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_CLICK; } @Override public boolean onRequest(final Intent request, final Intent response) { return registerEvent(request, response, getServiceID(request), getSessionKey(request)); } }; private final DConnectApi mDeleteOnClose = new DeleteApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_CLOSE; } @Override public boolean onRequest(final Intent request, final Intent response) { return unregisterEvent(request, response, getServiceID(request), getSessionKey(request)); } }; private final DConnectApi mPutOnClose = new PutApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_CLOSE; } @Override public boolean onRequest(final Intent request, final Intent response) { return registerEvent(request, response, getServiceID(request), getSessionKey(request)); } }; private final DConnectApi mDeleteOnShow = new DeleteApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_SHOW; } @Override public boolean onRequest(final Intent request, final Intent response) { return unregisterEvent(request, response, getServiceID(request), getSessionKey(request)); } }; private final DConnectApi mPutOnShow = new PutApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_SHOW; } @Override public boolean onRequest(final Intent request, final Intent response) { return registerEvent(request, response, getServiceID(request), getSessionKey(request)); } }; /** * イベントを登録します. * @param request リクエスト * @param response レスポンス * @param serviceId サービスID * @param sessionKey セッションキー * @return 同期なのでtrueを返却 */ private boolean registerEvent(final Intent request, final Intent response, final String serviceId, final String sessionKey) { if (serviceId == null) { MessageUtils.setEmptyServiceIdError(response); } else if (!WearUtils.checkServiceId(serviceId)) { MessageUtils.setNotFoundServiceError(response); } else { // Event registration. EventError error = EventManager.INSTANCE.addEvent(request); switch (error) { case NONE: setResult(response, DConnectMessage.RESULT_OK); break; case FAILED: MessageUtils.setUnknownError(response, "Do not register event."); break; case INVALID_PARAMETER: MessageUtils.setInvalidRequestParameterError(response); break; case NOT_FOUND: MessageUtils.setUnknownError(response, "Event not found."); break; default: MessageUtils.setUnknownError(response); break; } } return true; } /** * イベントを解除します. * @param request リクエスト * @param response レスポンス * @param serviceId サービスID * @param sessionKey セッションキー * @return 同期なのでtrueを返却 */ private boolean unregisterEvent(final Intent request, final Intent response, final String serviceId, final String sessionKey) { if (serviceId == null) { MessageUtils.setEmptyServiceIdError(response); } else if (!WearUtils.checkServiceId(serviceId)) { MessageUtils.setNotFoundServiceError(response); } else { // Event release. EventError error = EventManager.INSTANCE.removeEvent(request); switch (error) { case NONE: setResult(response, DConnectMessage.RESULT_OK); break; case FAILED: MessageUtils.setUnknownError(response, "Do not unregister event."); break; case INVALID_PARAMETER: MessageUtils.setInvalidRequestParameterError(response); break; case NOT_FOUND: MessageUtils.setUnknownError(response, "Event not found."); break; default: MessageUtils.setUnknownError(response); break; } } return true; } }