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