• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2017 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 package android.support.v4.content.pm;
17 
18 import android.content.ComponentName;
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.pm.ShortcutInfo;
22 import android.graphics.Bitmap;
23 import android.support.annotation.DrawableRes;
24 import android.support.annotation.NonNull;
25 import android.support.annotation.Nullable;
26 import android.support.annotation.RequiresApi;
27 import android.support.v4.graphics.drawable.IconCompat;
28 import android.text.TextUtils;
29 
30 import java.util.Arrays;
31 
32 /**
33  * Helper for accessing features in {@link android.content.pm.ShortcutInfo}
34  * introduced after API level 25 in a backwards compatible fashion.
35  */
36 public class ShortcutInfoCompat {
37 
38     private Context mContext;
39     private String mId;
40 
41     private Intent[] mIntents;
42     private ComponentName mActivity;
43 
44     private CharSequence mLabel;
45     private CharSequence mLongLabel;
46     private CharSequence mDisabledMessage;
47 
48     private IconCompat mIcon;
49 
ShortcutInfoCompat()50     private ShortcutInfoCompat() { }
51 
52     @RequiresApi(26)
toShortcutInfo()53     ShortcutInfo toShortcutInfo() {
54         ShortcutInfo.Builder builder = new ShortcutInfo.Builder(mContext, mId)
55                 .setShortLabel(mLabel)
56                 .setIntents(mIntents);
57         if (mIcon != null) {
58             builder.setIcon(mIcon.toIcon());
59         }
60         if (!TextUtils.isEmpty(mLongLabel)) {
61             builder.setLongLabel(mLongLabel);
62         }
63         if (!TextUtils.isEmpty(mDisabledMessage)) {
64             builder.setDisabledMessage(mDisabledMessage);
65         }
66         if (mActivity != null) {
67             builder.setActivity(mActivity);
68         }
69         return builder.build();
70     }
71 
addToIntent(Intent outIntent)72     Intent addToIntent(Intent outIntent) {
73         outIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, mIntents[mIntents.length - 1])
74                 .putExtra(Intent.EXTRA_SHORTCUT_NAME, mLabel.toString());
75         if (mIcon != null) {
76             mIcon.addToShortcutIntent(outIntent);
77         }
78         return outIntent;
79     }
80 
81     /**
82      * Returns the ID of a shortcut.
83      *
84      * <p>Shortcut IDs are unique within each publisher app and must be stable across
85      * devices so that shortcuts will still be valid when restored on a different device.
86      * See {@link android.content.pm.ShortcutManager} for details.
87      */
88     @NonNull
getId()89     public String getId() {
90         return mId;
91     }
92 
93     /**
94      * Return the target activity.
95      *
96      * <p>This has nothing to do with the activity that this shortcut will launch.
97      * Launcher apps should show the launcher icon for the returned activity alongside
98      * this shortcut.
99      *
100      * @see Builder#setActivity(ComponentName)
101      */
102     @Nullable
getActivity()103     public ComponentName getActivity() {
104         return mActivity;
105     }
106 
107     /**
108      * Return the short description of a shortcut.
109      *
110      * @see Builder#setShortLabel(CharSequence)
111      */
112     @NonNull
getShortLabel()113     public CharSequence getShortLabel() {
114         return mLabel;
115     }
116 
117     /**
118      * Return the long description of a shortcut.
119      *
120      * @see Builder#setLongLabel(CharSequence)
121      */
122     @Nullable
getLongLabel()123     public CharSequence getLongLabel() {
124         return mLongLabel;
125     }
126 
127     /**
128      * Return the message that should be shown when the user attempts to start a shortcut
129      * that is disabled.
130      *
131      * @see Builder#setDisabledMessage(CharSequence)
132      */
133     @Nullable
getDisabledMessage()134     public CharSequence getDisabledMessage() {
135         return mDisabledMessage;
136     }
137 
138     /**
139      * Returns the intent that is executed when the user selects this shortcut.
140      * If setIntents() was used, then return the last intent in the array.
141      *
142      * @see Builder#setIntent(Intent)
143      */
144     @NonNull
getIntent()145     public Intent getIntent() {
146         return mIntents[mIntents.length - 1];
147     }
148 
149     /**
150      * Return the intent set with {@link Builder#setIntents(Intent[])}.
151      *
152      * @see Builder#setIntents(Intent[])
153      */
154     @NonNull
getIntents()155     public Intent[] getIntents() {
156         return Arrays.copyOf(mIntents, mIntents.length);
157     }
158 
159     /**
160      * Builder class for {@link ShortcutInfoCompat} objects.
161      */
162     public static class Builder {
163 
164         private final ShortcutInfoCompat mInfo;
165 
Builder(@onNull Context context, @NonNull String id)166         public Builder(@NonNull Context context, @NonNull String id) {
167             mInfo = new ShortcutInfoCompat();
168             mInfo.mContext = context;
169             mInfo.mId = id;
170         }
171 
172         /**
173          * Sets the short title of a shortcut.
174          *
175          * <p>This is a mandatory field when publishing a new shortcut.
176          *
177          * <p>This field is intended to be a concise description of a shortcut.
178          *
179          * <p>The recommended maximum length is 10 characters.
180          */
181         @NonNull
setShortLabel(@onNull CharSequence shortLabel)182         public Builder setShortLabel(@NonNull CharSequence shortLabel) {
183             mInfo.mLabel = shortLabel;
184             return this;
185         }
186 
187         /**
188          * Sets the text of a shortcut.
189          *
190          * <p>This field is intended to be more descriptive than the shortcut title. The launcher
191          * shows this instead of the short title when it has enough space.
192          *
193          * <p>The recommend maximum length is 25 characters.
194          */
195         @NonNull
setLongLabel(@onNull CharSequence longLabel)196         public Builder setLongLabel(@NonNull CharSequence longLabel) {
197             mInfo.mLongLabel = longLabel;
198             return this;
199         }
200 
201         /**
202          * Sets the message that should be shown when the user attempts to start a shortcut that
203          * is disabled.
204          *
205          * @see ShortcutInfo#getDisabledMessage()
206          */
207         @NonNull
setDisabledMessage(@onNull CharSequence disabledMessage)208         public Builder setDisabledMessage(@NonNull CharSequence disabledMessage) {
209             mInfo.mDisabledMessage = disabledMessage;
210             return this;
211         }
212 
213         /**
214          * Sets the intent of a shortcut.  Alternatively, {@link #setIntents(Intent[])} can be used
215          * to launch an activity with other activities in the back stack.
216          *
217          * <p>This is a mandatory field when publishing a new shortcut.
218          *
219          * <p>The given {@code intent} can contain extras, but these extras must contain values
220          * of primitive types in order for the system to persist these values.
221          */
222         @NonNull
setIntent(@onNull Intent intent)223         public Builder setIntent(@NonNull Intent intent) {
224             return setIntents(new Intent[]{intent});
225         }
226 
227         /**
228          * Sets multiple intents instead of a single intent, in order to launch an activity with
229          * other activities in back stack.  Use {@link android.app.TaskStackBuilder} to build
230          * intents. The last element in the list represents the only intent that doesn't place
231          * an activity on the back stack.
232          */
233         @NonNull
setIntents(@onNull Intent[] intents)234         public Builder setIntents(@NonNull Intent[] intents) {
235             mInfo.mIntents = intents;
236             return this;
237         }
238 
239         /**
240          * Sets an icon of a shortcut.
241          * @deprecated use {@link #setIcon(IconCompat)} instead
242          */
243         @NonNull
setIcon(@onNull Bitmap icon)244         public Builder setIcon(@NonNull Bitmap icon) {
245             return setIcon(IconCompat.createWithBitmap(icon));
246         }
247 
248         /**
249          * Sets an icon of a shortcut.
250          * @deprecated use {@link #setIcon(IconCompat)} instead
251          */
252         @NonNull
setIcon(@rawableRes int icon)253         public Builder setIcon(@DrawableRes int icon) {
254             return setIcon(IconCompat.createWithResource(mInfo.mContext, icon));
255         }
256 
257         /**
258          * Sets an icon of a shortcut.
259          */
260         @NonNull
setIcon(IconCompat icon)261         public Builder setIcon(IconCompat icon) {
262             mInfo.mIcon = icon;
263             return this;
264         }
265 
266         /**
267          * Sets the target activity. A shortcut will be shown along with this activity's icon
268          * on the launcher.
269          *
270          * @see ShortcutInfo#getActivity()
271          * @see android.content.pm.ShortcutInfo.Builder#setActivity(ComponentName)
272          */
273         @NonNull
setActivity(@onNull ComponentName activity)274         public Builder setActivity(@NonNull ComponentName activity) {
275             mInfo.mActivity = activity;
276             return this;
277         }
278 
279         /**
280          * Creates a {@link ShortcutInfoCompat} instance.
281          */
282         @NonNull
build()283         public ShortcutInfoCompat build() {
284             // Verify the arguments
285             if (TextUtils.isEmpty(mInfo.mLabel)) {
286                 throw new IllegalArgumentException("Shortcut much have a non-empty label");
287             }
288             if (mInfo.mIntents == null || mInfo.mIntents.length == 0) {
289                 throw new IllegalArgumentException("Shortcut much have an intent");
290             }
291             return mInfo;
292         }
293     }
294 }
295