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 94 @Override build()95 public Notification build() { 96 b.setExtras(mExtras); 97 return b.build(); 98 } 99 } 100 addAction(Notification.Builder b, NotificationCompatBase.Action action)101 public static void addAction(Notification.Builder b, NotificationCompatBase.Action action) { 102 Notification.Action.Builder actionBuilder = new Notification.Action.Builder( 103 action.getIcon(), action.getTitle(), action.getActionIntent()); 104 if (action.getRemoteInputs() != null) { 105 for (RemoteInput remoteInput : RemoteInputCompatApi20.fromCompat( 106 action.getRemoteInputs())) { 107 actionBuilder.addRemoteInput(remoteInput); 108 } 109 } 110 if (action.getExtras() != null) { 111 actionBuilder.addExtras(action.getExtras()); 112 } 113 b.addAction(actionBuilder.build()); 114 } 115 getAction(Notification notif, int actionIndex, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)116 public static NotificationCompatBase.Action getAction(Notification notif, 117 int actionIndex, NotificationCompatBase.Action.Factory actionFactory, 118 RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) { 119 return getActionCompatFromAction(notif.actions[actionIndex], actionFactory, remoteInputFactory); 120 } 121 getActionCompatFromAction( Notification.Action action, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)122 private static NotificationCompatBase.Action getActionCompatFromAction( 123 Notification.Action action, NotificationCompatBase.Action.Factory actionFactory, 124 RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) { 125 RemoteInputCompatBase.RemoteInput[] remoteInputs = RemoteInputCompatApi20.toCompat( 126 action.getRemoteInputs(), remoteInputFactory); 127 return actionFactory.build(action.icon, action.title, action.actionIntent, 128 action.getExtras(), remoteInputs); 129 } 130 getActionFromActionCompat( NotificationCompatBase.Action actionCompat)131 private static Notification.Action getActionFromActionCompat( 132 NotificationCompatBase.Action actionCompat) { 133 Notification.Action.Builder actionBuilder = new Notification.Action.Builder( 134 actionCompat.getIcon(), actionCompat.getTitle(), actionCompat.getActionIntent()) 135 .addExtras(actionCompat.getExtras()); 136 RemoteInputCompatBase.RemoteInput[] remoteInputCompats = actionCompat.getRemoteInputs(); 137 if (remoteInputCompats != null) { 138 RemoteInput[] remoteInputs = RemoteInputCompatApi20.fromCompat(remoteInputCompats); 139 for (RemoteInput remoteInput : remoteInputs) { 140 actionBuilder.addRemoteInput(remoteInput); 141 } 142 } 143 return actionBuilder.build(); 144 } 145 146 /** 147 * Get a list of notification compat actions by parsing actions stored within a list of 148 * parcelables using the {@link Bundle#getParcelableArrayList} function in the same 149 * manner that framework code would do so. In API20, Using Action parcelable directly 150 * is correct. 151 */ getActionsFromParcelableArrayList( ArrayList<Parcelable> parcelables, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)152 public static NotificationCompatBase.Action[] getActionsFromParcelableArrayList( 153 ArrayList<Parcelable> parcelables, 154 NotificationCompatBase.Action.Factory actionFactory, 155 RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) { 156 if (parcelables == null) { 157 return null; 158 } 159 NotificationCompatBase.Action[] actions = actionFactory.newArray(parcelables.size()); 160 for (int i = 0; i < actions.length; i++) { 161 Notification.Action action = (Notification.Action) parcelables.get(i); 162 actions[i] = getActionCompatFromAction(action, actionFactory, remoteInputFactory); 163 } 164 return actions; 165 } 166 167 /** 168 * Get an array list of parcelables, suitable for {@link Bundle#putParcelableArrayList}, 169 * that matches what framework code would do to store an actions list in this way. In API20, 170 * action parcelables were directly placed as entries in the array list. 171 */ getParcelableArrayListForActions( NotificationCompatBase.Action[] actions)172 public static ArrayList<Parcelable> getParcelableArrayListForActions( 173 NotificationCompatBase.Action[] actions) { 174 if (actions == null) { 175 return null; 176 } 177 ArrayList<Parcelable> parcelables = new ArrayList<Parcelable>(actions.length); 178 for (NotificationCompatBase.Action action : actions) { 179 parcelables.add(getActionFromActionCompat(action)); 180 } 181 return parcelables; 182 } 183 getLocalOnly(Notification notif)184 public static boolean getLocalOnly(Notification notif) { 185 return (notif.flags & Notification.FLAG_LOCAL_ONLY) != 0; 186 } 187 getGroup(Notification notif)188 public static String getGroup(Notification notif) { 189 return notif.getGroup(); 190 } 191 isGroupSummary(Notification notif)192 public static boolean isGroupSummary(Notification notif) { 193 return (notif.flags & Notification.FLAG_GROUP_SUMMARY) != 0; 194 } 195 getSortKey(Notification notif)196 public static String getSortKey(Notification notif) { 197 return notif.getSortKey(); 198 } 199 } 200