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 android.support.v4.app; 18 19 import android.app.Notification; 20 import android.app.PendingIntent; 21 import android.app.RemoteInput; 22 import android.content.Context; 23 import android.graphics.Bitmap; 24 import android.os.Bundle; 25 import android.os.Parcelable; 26 import android.widget.RemoteViews; 27 28 import java.util.ArrayList; 29 30 class NotificationCompatApi20 { 31 public static class Builder implements NotificationBuilderWithBuilderAccessor, 32 NotificationBuilderWithActions { 33 private Notification.Builder b; 34 private Bundle mExtras; 35 Builder(Context context, Notification n, CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo, RemoteViews tickerView, int number, PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon, int progressMax, int progress, boolean progressIndeterminate, boolean showWhen, boolean useChronometer, int priority, CharSequence subText, boolean localOnly, ArrayList<String> people, Bundle extras, String groupKey, boolean groupSummary, String sortKey)36 public Builder(Context context, Notification n, 37 CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo, 38 RemoteViews tickerView, int number, 39 PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon, 40 int progressMax, int progress, boolean progressIndeterminate, boolean showWhen, 41 boolean useChronometer, int priority, CharSequence subText, boolean localOnly, 42 ArrayList<String> people, Bundle extras, String groupKey, boolean groupSummary, 43 String sortKey) { 44 b = new Notification.Builder(context) 45 .setWhen(n.when) 46 .setShowWhen(showWhen) 47 .setSmallIcon(n.icon, n.iconLevel) 48 .setContent(n.contentView) 49 .setTicker(n.tickerText, tickerView) 50 .setSound(n.sound, n.audioStreamType) 51 .setVibrate(n.vibrate) 52 .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS) 53 .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0) 54 .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) 55 .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0) 56 .setDefaults(n.defaults) 57 .setContentTitle(contentTitle) 58 .setContentText(contentText) 59 .setSubText(subText) 60 .setContentInfo(contentInfo) 61 .setContentIntent(contentIntent) 62 .setDeleteIntent(n.deleteIntent) 63 .setFullScreenIntent(fullScreenIntent, 64 (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0) 65 .setLargeIcon(largeIcon) 66 .setNumber(number) 67 .setUsesChronometer(useChronometer) 68 .setPriority(priority) 69 .setProgress(progressMax, progress, progressIndeterminate) 70 .setLocalOnly(localOnly) 71 .setGroup(groupKey) 72 .setGroupSummary(groupSummary) 73 .setSortKey(sortKey); 74 mExtras = new Bundle(); 75 if (extras != null) { 76 mExtras.putAll(extras); 77 } 78 if (people != null && !people.isEmpty()) { 79 mExtras.putStringArray(Notification.EXTRA_PEOPLE, 80 people.toArray(new String[people.size()])); 81 } 82 } 83 84 @Override addAction(NotificationCompatBase.Action action)85 public void addAction(NotificationCompatBase.Action action) { 86 NotificationCompatApi20.addAction(b, action); 87 } 88 89 @Override getBuilder()90 public Notification.Builder getBuilder() { 91 return b; 92 } 93 build()94 public Notification build() { 95 b.setExtras(mExtras); 96 return b.build(); 97 } 98 } 99 addAction(Notification.Builder b, NotificationCompatBase.Action action)100 public static void addAction(Notification.Builder b, NotificationCompatBase.Action action) { 101 Notification.Action.Builder actionBuilder = new Notification.Action.Builder( 102 action.getIcon(), action.getTitle(), action.getActionIntent()); 103 if (action.getRemoteInputs() != null) { 104 for (RemoteInput remoteInput : RemoteInputCompatApi20.fromCompat( 105 action.getRemoteInputs())) { 106 actionBuilder.addRemoteInput(remoteInput); 107 } 108 } 109 if (action.getExtras() != null) { 110 actionBuilder.addExtras(action.getExtras()); 111 } 112 b.addAction(actionBuilder.build()); 113 } 114 getAction(Notification notif, int actionIndex, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)115 public static NotificationCompatBase.Action getAction(Notification notif, 116 int actionIndex, NotificationCompatBase.Action.Factory actionFactory, 117 RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) { 118 return getActionCompatFromAction(notif.actions[actionIndex], actionFactory, remoteInputFactory); 119 } 120 getActionCompatFromAction( Notification.Action action, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)121 private static NotificationCompatBase.Action getActionCompatFromAction( 122 Notification.Action action, NotificationCompatBase.Action.Factory actionFactory, 123 RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) { 124 RemoteInputCompatBase.RemoteInput[] remoteInputs = RemoteInputCompatApi20.toCompat( 125 action.getRemoteInputs(), remoteInputFactory); 126 return actionFactory.build(action.icon, action.title, action.actionIntent, 127 action.getExtras(), remoteInputs); 128 } 129 getActionFromActionCompat( NotificationCompatBase.Action actionCompat)130 private static Notification.Action getActionFromActionCompat( 131 NotificationCompatBase.Action actionCompat) { 132 Notification.Action.Builder actionBuilder = new Notification.Action.Builder( 133 actionCompat.getIcon(), actionCompat.getTitle(), actionCompat.getActionIntent()) 134 .addExtras(actionCompat.getExtras()); 135 RemoteInputCompatBase.RemoteInput[] remoteInputCompats = actionCompat.getRemoteInputs(); 136 if (remoteInputCompats != null) { 137 RemoteInput[] remoteInputs = RemoteInputCompatApi20.fromCompat(remoteInputCompats); 138 for (RemoteInput remoteInput : remoteInputs) { 139 actionBuilder.addRemoteInput(remoteInput); 140 } 141 } 142 return actionBuilder.build(); 143 } 144 145 /** 146 * Get a list of notification compat actions by parsing actions stored within a list of 147 * parcelables using the {@link Bundle#getParcelableArrayList} function in the same 148 * manner that framework code would do so. In API20, Using Action parcelable directly 149 * is correct. 150 */ getActionsFromParcelableArrayList( ArrayList<Parcelable> parcelables, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)151 public static NotificationCompatBase.Action[] getActionsFromParcelableArrayList( 152 ArrayList<Parcelable> parcelables, 153 NotificationCompatBase.Action.Factory actionFactory, 154 RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) { 155 if (parcelables == null) { 156 return null; 157 } 158 NotificationCompatBase.Action[] actions = actionFactory.newArray(parcelables.size()); 159 for (int i = 0; i < actions.length; i++) { 160 Notification.Action action = (Notification.Action) parcelables.get(i); 161 actions[i] = getActionCompatFromAction(action, actionFactory, remoteInputFactory); 162 } 163 return actions; 164 } 165 166 /** 167 * Get an array list of parcelables, suitable for {@link Bundle#putParcelableArrayList}, 168 * that matches what framework code would do to store an actions list in this way. In API20, 169 * action parcelables were directly placed as entries in the array list. 170 */ getParcelableArrayListForActions( NotificationCompatBase.Action[] actions)171 public static ArrayList<Parcelable> getParcelableArrayListForActions( 172 NotificationCompatBase.Action[] actions) { 173 if (actions == null) { 174 return null; 175 } 176 ArrayList<Parcelable> parcelables = new ArrayList<Parcelable>(actions.length); 177 for (NotificationCompatBase.Action action : actions) { 178 parcelables.add(getActionFromActionCompat(action)); 179 } 180 return parcelables; 181 } 182 getLocalOnly(Notification notif)183 public static boolean getLocalOnly(Notification notif) { 184 return (notif.flags & Notification.FLAG_LOCAL_ONLY) != 0; 185 } 186 getGroup(Notification notif)187 public static String getGroup(Notification notif) { 188 return notif.getGroup(); 189 } 190 isGroupSummary(Notification notif)191 public static boolean isGroupSummary(Notification notif) { 192 return (notif.flags & Notification.FLAG_GROUP_SUMMARY) != 0; 193 } 194 getSortKey(Notification notif)195 public static String getSortKey(Notification notif) { 196 return notif.getSortKey(); 197 } 198 } 199