ChooserTarget.java revision 7d7580019e44e2e162df01ffff51de20ed0721b3
1/* 2 * Copyright (C) 2015 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 18package android.service.chooser; 19 20import android.app.Activity; 21import android.app.PendingIntent; 22import android.content.ComponentName; 23import android.content.Context; 24import android.content.Intent; 25import android.content.IntentFilter; 26import android.content.IntentSender; 27import android.graphics.Bitmap; 28import android.os.Bundle; 29import android.os.Parcel; 30import android.os.Parcelable; 31import android.os.UserHandle; 32import android.util.Log; 33 34/** 35 * A ChooserTarget represents a deep-link into an application as returned by a 36 * {@link android.service.chooser.ChooserTargetService}. 37 */ 38public final class ChooserTarget implements Parcelable { 39 private static final String TAG = "ChooserTarget"; 40 41 /** 42 * The title of this target that will be shown to the user. The title may be truncated 43 * if it is too long to display in the space provided. 44 */ 45 private CharSequence mTitle; 46 47 /** 48 * The icon that will be shown to the user to represent this target. 49 * The system may resize this icon as appropriate. 50 */ 51 private Bitmap mIcon; 52 53 /** 54 * The IntentSender that will be used to deliver the intent to the target. 55 * It will be {@link android.content.Intent#fillIn(android.content.Intent, int)} filled in} 56 * by the real intent sent by the application. 57 */ 58 private IntentSender mIntentSender; 59 60 /** 61 * The score given to this item. It can be normalized. 62 */ 63 private float mScore; 64 65 /** 66 * Construct a deep link target for presentation by a chooser UI. 67 * 68 * <p>A target is composed of a title and an icon for presentation to the user. 69 * The UI presenting this target may truncate the title if it is too long to be presented 70 * in the available space, as well as crop, resize or overlay the supplied icon.</p> 71 * 72 * <p>The creator of a target may supply a ranking score. This score is assumed to be relative 73 * to the other targets supplied by the same 74 * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}. 75 * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match). 76 * Scores for a set of targets do not need to sum to 1.</p> 77 * 78 * <p>Before being sent, the PendingIntent supplied will be 79 * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied 80 * to the chooser. When constructing a PendingIntent for use in a ChooserTarget, make sure 81 * that you permit the relevant fields to be filled in using the appropriate flags such as 82 * {@link Intent#FILL_IN_ACTION}, {@link Intent#FILL_IN_CATEGORIES}, 83 * {@link Intent#FILL_IN_DATA} and {@link Intent#FILL_IN_CLIP_DATA}. Note that 84 * {@link Intent#FILL_IN_CLIP_DATA} is required to appropriately receive URI permission grants 85 * for {@link Intent#ACTION_SEND} intents.</p> 86 * 87 * <p>Take care not to place custom {@link android.os.Parcelable} types into 88 * the PendingIntent as extras, as the system will not be able to unparcel it to merge 89 * additional extras.</p> 90 * 91 * @param title title of this target that will be shown to a user 92 * @param icon icon to represent this target 93 * @param score ranking score for this target between 0.0f and 1.0f, inclusive 94 * @param pendingIntent PendingIntent to fill in and send if the user chooses this target 95 */ 96 public ChooserTarget(CharSequence title, Bitmap icon, float score, 97 PendingIntent pendingIntent) { 98 this(title, icon, score, pendingIntent.getIntentSender()); 99 } 100 101 /** 102 * Construct a deep link target for presentation by a chooser UI. 103 * 104 * <p>A target is composed of a title and an icon for presentation to the user. 105 * The UI presenting this target may truncate the title if it is too long to be presented 106 * in the available space, as well as crop, resize or overlay the supplied icon.</p> 107 * 108 * <p>The creator of a target may supply a ranking score. This score is assumed to be relative 109 * to the other targets supplied by the same 110 * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}. 111 * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match). 112 * Scores for a set of targets do not need to sum to 1.</p> 113 * 114 * <p>Before being sent, the IntentSender supplied will be 115 * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied 116 * to the chooser. When constructing an IntentSender for use in a ChooserTarget, make sure 117 * that you permit the relevant fields to be filled in using the appropriate flags such as 118 * {@link Intent#FILL_IN_ACTION}, {@link Intent#FILL_IN_CATEGORIES}, 119 * {@link Intent#FILL_IN_DATA} and {@link Intent#FILL_IN_CLIP_DATA}. Note that 120 * {@link Intent#FILL_IN_CLIP_DATA} is required to appropriately receive URI permission grants 121 * for {@link Intent#ACTION_SEND} intents.</p> 122 * 123 * <p>Take care not to place custom {@link android.os.Parcelable} types into 124 * the IntentSender as extras, as the system will not be able to unparcel it to merge 125 * additional extras.</p> 126 * 127 * @param title title of this target that will be shown to a user 128 * @param icon icon to represent this target 129 * @param score ranking score for this target between 0.0f and 1.0f, inclusive 130 * @param intentSender IntentSender to fill in and send if the user chooses this target 131 */ 132 public ChooserTarget(CharSequence title, Bitmap icon, float score, IntentSender intentSender) { 133 mTitle = title; 134 mIcon = icon; 135 if (score > 1.f || score < 0.f) { 136 throw new IllegalArgumentException("Score " + score + " out of range; " 137 + "must be between 0.0f and 1.0f"); 138 } 139 mScore = score; 140 mIntentSender = intentSender; 141 } 142 143 ChooserTarget(Parcel in) { 144 mTitle = in.readCharSequence(); 145 if (in.readInt() != 0) { 146 mIcon = Bitmap.CREATOR.createFromParcel(in); 147 } else { 148 mIcon = null; 149 } 150 mScore = in.readFloat(); 151 mIntentSender = IntentSender.readIntentSenderOrNullFromParcel(in); 152 } 153 154 /** 155 * Returns the title of this target for display to a user. The UI displaying the title 156 * may truncate this title if it is too long to be displayed in full. 157 * 158 * @return the title of this target, intended to be shown to a user 159 */ 160 public CharSequence getTitle() { 161 return mTitle; 162 } 163 164 /** 165 * Returns the icon representing this target for display to a user. The UI displaying the icon 166 * may crop, resize or overlay this icon. 167 * 168 * @return the icon representing this target, intended to be shown to a user 169 */ 170 public Bitmap getIcon() { 171 return mIcon; 172 } 173 174 /** 175 * Returns the ranking score supplied by the creator of this ChooserTarget. 176 * Values are between 0.0f and 1.0f. The UI displaying the target may 177 * take this score into account when sorting and merging targets from multiple sources. 178 * 179 * @return the ranking score for this target between 0.0f and 1.0f, inclusive 180 */ 181 public float getScore() { 182 return mScore; 183 } 184 185 /** 186 * Returns the raw IntentSender supplied by the ChooserTarget's creator. 187 * This may be null if the creator specified a regular Intent instead. 188 * 189 * <p>To fill in and send the intent, see {@link #sendIntent(Context, Intent)}.</p> 190 * 191 * @return the IntentSender supplied by the ChooserTarget's creator 192 */ 193 public IntentSender getIntentSender() { 194 return mIntentSender; 195 } 196 197 /** 198 * Fill in the IntentSender supplied by the ChooserTarget's creator and send it. 199 * 200 * @param context the sending Context; generally the Activity presenting the chooser UI 201 * @param fillInIntent the Intent provided to the Chooser to be sent to a selected target 202 * @return true if sending the Intent was successful 203 */ 204 public boolean sendIntent(Context context, Intent fillInIntent) { 205 if (fillInIntent != null) { 206 fillInIntent.migrateExtraStreamToClipData(); 207 fillInIntent.prepareToLeaveProcess(); 208 } 209 if (mIntentSender != null) { 210 try { 211 mIntentSender.sendIntent(context, 0, fillInIntent, null, null); 212 return true; 213 } catch (IntentSender.SendIntentException e) { 214 Log.e(TAG, "sendIntent " + this + " failed", e); 215 return false; 216 } 217 } else { 218 Log.e(TAG, "sendIntent " + this + " failed - no IntentSender to send"); 219 return false; 220 } 221 } 222 223 @Override 224 public String toString() { 225 return "ChooserTarget{" 226 + (mIntentSender != null ? mIntentSender.getCreatorPackage() : null) 227 + ", " 228 + "'" + mTitle 229 + "', " + mScore + "}"; 230 } 231 232 @Override 233 public int describeContents() { 234 return 0; 235 } 236 237 @Override 238 public void writeToParcel(Parcel dest, int flags) { 239 dest.writeCharSequence(mTitle); 240 if (mIcon != null) { 241 dest.writeInt(1); 242 mIcon.writeToParcel(dest, 0); 243 } else { 244 dest.writeInt(0); 245 } 246 dest.writeFloat(mScore); 247 IntentSender.writeIntentSenderOrNullToParcel(mIntentSender, dest); 248 } 249 250 public static final Creator<ChooserTarget> CREATOR 251 = new Creator<ChooserTarget>() { 252 @Override 253 public ChooserTarget createFromParcel(Parcel source) { 254 return new ChooserTarget(source); 255 } 256 257 @Override 258 public ChooserTarget[] newArray(int size) { 259 return new ChooserTarget[size]; 260 } 261 }; 262} 263