1 /* 2 * Copyright (C) 2008 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.telephony; 18 19 import android.Manifest; 20 import android.annotation.CallbackExecutor; 21 import android.annotation.IntDef; 22 import android.annotation.IntRange; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.RequiresFeature; 26 import android.annotation.RequiresPermission; 27 import android.annotation.SuppressAutoDoc; 28 import android.annotation.SystemApi; 29 import android.annotation.TestApi; 30 import android.app.PendingIntent; 31 import android.compat.Compatibility; 32 import android.compat.annotation.ChangeId; 33 import android.compat.annotation.EnabledAfter; 34 import android.compat.annotation.UnsupportedAppUsage; 35 import android.content.Context; 36 import android.content.pm.PackageManager; 37 import android.database.CursorWindow; 38 import android.net.Uri; 39 import android.os.Build; 40 import android.os.Bundle; 41 import android.os.RemoteException; 42 import android.text.TextUtils; 43 import android.util.ArrayMap; 44 import android.util.Log; 45 import android.util.Pair; 46 47 import com.android.internal.annotations.GuardedBy; 48 import com.android.internal.telephony.IIntegerConsumer; 49 import com.android.internal.telephony.ISms; 50 import com.android.internal.telephony.ITelephony; 51 import com.android.internal.telephony.SmsRawData; 52 import com.android.telephony.Rlog; 53 54 import java.lang.annotation.Retention; 55 import java.lang.annotation.RetentionPolicy; 56 import java.util.ArrayList; 57 import java.util.List; 58 import java.util.Map; 59 import java.util.concurrent.Executor; 60 61 /* 62 * TODO(code review): Curious question... Why are a lot of these 63 * methods not declared as static, since they do not seem to require 64 * any local object state? Presumably this cannot be changed without 65 * interfering with the API... 66 */ 67 68 /** 69 * Manages SMS operations such as sending data, text, and pdu SMS messages. 70 * Get this object by calling the static method {@link #getDefault()}. To create an instance of 71 * {@link SmsManager} associated with a specific subscription ID, call 72 * {@link #getSmsManagerForSubscriptionId(int)}. This is typically used for devices that support 73 * multiple active subscriptions at once. 74 * 75 * <p>For information about how to behave as the default SMS app on Android 4.4 (API level 19) 76 * and higher, see {@link android.provider.Telephony}. 77 * 78 * @see SubscriptionManager#getActiveSubscriptionInfoList() 79 */ 80 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING) 81 public final class SmsManager { 82 private static final String TAG = "SmsManager"; 83 84 private static final Object sLockObject = new Object(); 85 86 @GuardedBy("sLockObject") 87 private static final Map<Pair<Context, Integer>, SmsManager> sSubInstances = 88 new ArrayMap<>(); 89 90 /** Singleton object constructed during class initialization. */ 91 private static final SmsManager DEFAULT_INSTANCE = getSmsManagerForContextAndSubscriptionId( 92 null, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 93 94 /** SMS record length from TS 51.011 10.5.3 95 * @hide 96 */ 97 public static final int SMS_RECORD_LENGTH = 176; 98 99 /** SMS record length from C.S0023 3.4.27 100 * @hide 101 */ 102 public static final int CDMA_SMS_RECORD_LENGTH = 255; 103 104 /** A concrete subscription id, or the pseudo DEFAULT_SUBSCRIPTION_ID */ 105 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 106 private int mSubId; 107 108 /** 109 * Context this SmsManager is for. Can be {@code null} in the case the manager was created via 110 * legacy APIs 111 */ 112 private final @Nullable Context mContext; 113 114 /* 115 * Key for the various carrier-dependent configuration values. 116 * Some of the values are used by the system in processing SMS or MMS messages. Others 117 * are provided for the convenience of SMS applications. 118 */ 119 120 /** 121 * Whether to append transaction id to MMS WAP Push M-Notification.ind's content location URI 122 * when constructing the download URL of a new MMS (boolean type) 123 */ 124 public static final String MMS_CONFIG_APPEND_TRANSACTION_ID = 125 CarrierConfigManager.KEY_MMS_APPEND_TRANSACTION_ID_BOOL; 126 /** 127 * Whether MMS is enabled for the current carrier (boolean type) 128 */ 129 public static final String 130 MMS_CONFIG_MMS_ENABLED = CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL; 131 /** 132 * Whether group MMS is enabled for the current carrier (boolean type) 133 */ 134 public static final String 135 MMS_CONFIG_GROUP_MMS_ENABLED = CarrierConfigManager.KEY_MMS_GROUP_MMS_ENABLED_BOOL; 136 /** 137 * If this is enabled, M-NotifyResp.ind should be sent to the WAP Push content location instead 138 * of the default MMSC (boolean type) 139 */ 140 public static final String MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED = 141 CarrierConfigManager.KEY_MMS_NOTIFY_WAP_MMSC_ENABLED_BOOL; 142 /** 143 * Whether alias is enabled (boolean type) 144 */ 145 public static final String 146 MMS_CONFIG_ALIAS_ENABLED = CarrierConfigManager.KEY_MMS_ALIAS_ENABLED_BOOL; 147 /** 148 * Whether audio is allowed to be attached for MMS messages (boolean type) 149 */ 150 public static final String 151 MMS_CONFIG_ALLOW_ATTACH_AUDIO = CarrierConfigManager.KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL; 152 /** 153 * Whether multipart SMS is enabled (boolean type) 154 */ 155 public static final String MMS_CONFIG_MULTIPART_SMS_ENABLED = 156 CarrierConfigManager.KEY_MMS_MULTIPART_SMS_ENABLED_BOOL; 157 /** 158 * Whether SMS delivery report is enabled (boolean type) 159 */ 160 public static final String MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED = 161 CarrierConfigManager.KEY_MMS_SMS_DELIVERY_REPORT_ENABLED_BOOL; 162 /** 163 * Whether content-disposition field should be expected in an MMS PDU (boolean type) 164 */ 165 public static final String MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION = 166 CarrierConfigManager.KEY_MMS_SUPPORT_MMS_CONTENT_DISPOSITION_BOOL; 167 /** 168 * Whether multipart SMS should be sent as separate messages 169 */ 170 public static final String MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES = 171 CarrierConfigManager.KEY_MMS_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES_BOOL; 172 /** 173 * Whether MMS read report is enabled (boolean type) 174 */ 175 public static final String MMS_CONFIG_MMS_READ_REPORT_ENABLED = 176 CarrierConfigManager.KEY_MMS_MMS_READ_REPORT_ENABLED_BOOL; 177 /** 178 * Whether MMS delivery report is enabled (boolean type) 179 */ 180 public static final String MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED = 181 CarrierConfigManager.KEY_MMS_MMS_DELIVERY_REPORT_ENABLED_BOOL; 182 /** 183 * Max MMS message size in bytes (int type) 184 */ 185 public static final String 186 MMS_CONFIG_MAX_MESSAGE_SIZE = CarrierConfigManager.KEY_MMS_MAX_MESSAGE_SIZE_INT; 187 /** 188 * Max MMS image width (int type) 189 */ 190 public static final String 191 MMS_CONFIG_MAX_IMAGE_WIDTH = CarrierConfigManager.KEY_MMS_MAX_IMAGE_WIDTH_INT; 192 /** 193 * Max MMS image height (int type) 194 */ 195 public static final String 196 MMS_CONFIG_MAX_IMAGE_HEIGHT = CarrierConfigManager.KEY_MMS_MAX_IMAGE_HEIGHT_INT; 197 /** 198 * Limit of recipients of MMS messages (int type) 199 */ 200 public static final String 201 MMS_CONFIG_RECIPIENT_LIMIT = CarrierConfigManager.KEY_MMS_RECIPIENT_LIMIT_INT; 202 /** 203 * Min alias character count (int type) 204 */ 205 public static final String 206 MMS_CONFIG_ALIAS_MIN_CHARS = CarrierConfigManager.KEY_MMS_ALIAS_MIN_CHARS_INT; 207 /** 208 * Max alias character count (int type) 209 */ 210 public static final String 211 MMS_CONFIG_ALIAS_MAX_CHARS = CarrierConfigManager.KEY_MMS_ALIAS_MAX_CHARS_INT; 212 /** 213 * When the number of parts of a multipart SMS reaches this threshold, it should be converted 214 * into an MMS (int type) 215 */ 216 public static final String MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD = 217 CarrierConfigManager.KEY_MMS_SMS_TO_MMS_TEXT_THRESHOLD_INT; 218 /** 219 * Some carriers require SMS to be converted into MMS when text length reaches this threshold 220 * (int type) 221 */ 222 public static final String MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD = 223 CarrierConfigManager.KEY_MMS_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD_INT; 224 /** 225 * Max message text size (int type) 226 */ 227 public static final String MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE = 228 CarrierConfigManager.KEY_MMS_MESSAGE_TEXT_MAX_SIZE_INT; 229 /** 230 * Max message subject length (int type) 231 */ 232 public static final String 233 MMS_CONFIG_SUBJECT_MAX_LENGTH = CarrierConfigManager.KEY_MMS_SUBJECT_MAX_LENGTH_INT; 234 /** 235 * MMS HTTP socket timeout in milliseconds (int type) 236 */ 237 public static final String 238 MMS_CONFIG_HTTP_SOCKET_TIMEOUT = CarrierConfigManager.KEY_MMS_HTTP_SOCKET_TIMEOUT_INT; 239 /** 240 * The name of the UA Prof URL HTTP header for MMS HTTP request (String type) 241 */ 242 public static final String 243 MMS_CONFIG_UA_PROF_TAG_NAME = CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING; 244 /** 245 * The User-Agent header value for MMS HTTP request (String type) 246 */ 247 public static final String 248 MMS_CONFIG_USER_AGENT = CarrierConfigManager.KEY_MMS_USER_AGENT_STRING; 249 /** 250 * The UA Profile URL header value for MMS HTTP request (String type) 251 */ 252 public static final String 253 MMS_CONFIG_UA_PROF_URL = CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING; 254 /** 255 * A list of HTTP headers to add to MMS HTTP request, separated by "|" (String type) 256 */ 257 public static final String 258 MMS_CONFIG_HTTP_PARAMS = CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING; 259 /** 260 * Email gateway number (String type) 261 */ 262 public static final String MMS_CONFIG_EMAIL_GATEWAY_NUMBER = 263 CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING; 264 /** 265 * The suffix to append to the NAI header value for MMS HTTP request (String type) 266 */ 267 public static final String 268 MMS_CONFIG_NAI_SUFFIX = CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING; 269 /** 270 * If true, show the cell broadcast (amber alert) in the SMS settings. Some carriers don't want 271 * this shown. (Boolean type) 272 */ 273 public static final String MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS = 274 CarrierConfigManager.KEY_MMS_SHOW_CELL_BROADCAST_APP_LINKS_BOOL; 275 /** 276 * Whether the carrier MMSC supports charset field in Content-Type header. If this is false, 277 * then we don't add "charset" to "Content-Type" 278 */ 279 public static final String MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER = 280 CarrierConfigManager.KEY_MMS_SUPPORT_HTTP_CHARSET_HEADER_BOOL; 281 /** 282 * If true, add "Connection: close" header to MMS HTTP requests so the connection 283 * is immediately closed (disabling keep-alive). (Boolean type) 284 * @hide 285 */ 286 public static final String MMS_CONFIG_CLOSE_CONNECTION = 287 CarrierConfigManager.KEY_MMS_CLOSE_CONNECTION_BOOL; 288 289 /** 290 * 3gpp2 SMS priority is not specified 291 * @hide 292 */ 293 public static final int SMS_MESSAGE_PRIORITY_NOT_SPECIFIED = -1; 294 /** 295 * 3gpp SMS period is not specified 296 * @hide 297 */ 298 public static final int SMS_MESSAGE_PERIOD_NOT_SPECIFIED = -1; 299 300 /** @hide */ 301 @IntDef(prefix = { "PREMIUM_SMS_CONSENT" }, value = { 302 SmsManager.PREMIUM_SMS_CONSENT_UNKNOWN, 303 SmsManager.PREMIUM_SMS_CONSENT_ASK_USER, 304 SmsManager.PREMIUM_SMS_CONSENT_NEVER_ALLOW, 305 SmsManager.PREMIUM_SMS_CONSENT_ALWAYS_ALLOW 306 }) 307 @Retention(RetentionPolicy.SOURCE) 308 public @interface PremiumSmsConsent {} 309 310 /** Premium SMS Consent for the package is unknown. This indicates that the user 311 * has not set a permission for this package, because this package has never tried 312 * to send a premium SMS. 313 * @hide 314 */ 315 @SystemApi 316 public static final int PREMIUM_SMS_CONSENT_UNKNOWN = 0; 317 318 /** Default premium SMS Consent (ask user for each premium SMS sent). 319 * @hide 320 */ 321 @SystemApi 322 public static final int PREMIUM_SMS_CONSENT_ASK_USER = 1; 323 324 /** Premium SMS Consent when the owner has denied the app from sending premium SMS. 325 * @hide 326 */ 327 @SystemApi 328 public static final int PREMIUM_SMS_CONSENT_NEVER_ALLOW = 2; 329 330 /** Premium SMS Consent when the owner has allowed the app to send premium SMS. 331 * @hide 332 */ 333 @SystemApi 334 public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; 335 336 // result of asking the user for a subscription to perform an operation. 337 private interface SubscriptionResolverResult { onSuccess(int subId)338 void onSuccess(int subId); onFailure()339 void onFailure(); 340 } 341 342 /** 343 * Get {@link Context#getOpPackageName()} if this manager has a context, otherwise a dummy 344 * value. 345 * 346 * @return The package name to be used for app-ops checks 347 */ getOpPackageName()348 private @Nullable String getOpPackageName() { 349 if (mContext == null) { 350 return null; 351 } else { 352 return mContext.getOpPackageName(); 353 } 354 } 355 356 /** 357 * Get {@link Context#getAttributionTag()} ()} if this manager has a context, otherwise get the 358 * default attribution tag. 359 * 360 * @return The attribution tag to be used for app-ops checks 361 */ getAttributionTag()362 private @Nullable String getAttributionTag() { 363 if (mContext == null) { 364 return null; 365 } else { 366 return mContext.getAttributionTag(); 367 } 368 } 369 370 /** 371 * Send a text based SMS. 372 * 373 * <p class="note"><strong>Note:</strong> Using this method requires that your app has the 374 * {@link android.Manifest.permission#SEND_SMS} permission.</p> 375 * 376 * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if 377 * <em>and only if</em> an app is not selected as the default SMS app, the system automatically 378 * writes messages sent using this method to the SMS Provider (the default SMS app is always 379 * responsible for writing its sent messages to the SMS Provider). For information about 380 * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p> 381 * 382 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 383 * manager on a multi-SIM device, this operation may fail sending the SMS message because no 384 * suitable default subscription could be found. In this case, if {@code sentIntent} is 385 * non-null, then the {@link PendingIntent} will be sent with an error code 386 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the 387 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions 388 * where this operation may fail. 389 * </p> 390 * 391 * @param destinationAddress the address to send the message to 392 * @param scAddress is the service center address or null to use 393 * the current default SMSC 394 * @param text the body of the message to send 395 * @param sentIntent if not NULL this <code>PendingIntent</code> is 396 * broadcast when the message is successfully sent, or failed. 397 * The result code will be <code>Activity.RESULT_OK</code> for success, 398 * or one of these errors:<br> 399 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 400 * <code>RESULT_ERROR_RADIO_OFF</code><br> 401 * <code>RESULT_ERROR_NULL_PDU</code><br> 402 * <code>RESULT_ERROR_NO_SERVICE</code><br> 403 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br> 404 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 405 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 406 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 407 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br> 408 * <code>RESULT_NETWORK_REJECT</code><br> 409 * <code>RESULT_INVALID_ARGUMENTS</code><br> 410 * <code>RESULT_INVALID_STATE</code><br> 411 * <code>RESULT_NO_MEMORY</code><br> 412 * <code>RESULT_INVALID_SMS_FORMAT</code><br> 413 * <code>RESULT_SYSTEM_ERROR</code><br> 414 * <code>RESULT_MODEM_ERROR</code><br> 415 * <code>RESULT_NETWORK_ERROR</code><br> 416 * <code>RESULT_ENCODING_ERROR</code><br> 417 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br> 418 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br> 419 * <code>RESULT_INTERNAL_ERROR</code><br> 420 * <code>RESULT_NO_RESOURCES</code><br> 421 * <code>RESULT_CANCELLED</code><br> 422 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br> 423 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br> 424 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 425 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br> 426 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 427 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 428 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br> 429 * <code>RESULT_REMOTE_EXCEPTION</code><br> 430 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br> 431 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 432 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 433 * <code>RESULT_RIL_NETWORK_REJECT</code><br> 434 * <code>RESULT_RIL_INVALID_STATE</code><br> 435 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br> 436 * <code>RESULT_RIL_NO_MEMORY</code><br> 437 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 438 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br> 439 * <code>RESULT_RIL_SYSTEM_ERR</code><br> 440 * <code>RESULT_RIL_ENCODING_ERR</code><br> 441 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 442 * <code>RESULT_RIL_MODEM_ERR</code><br> 443 * <code>RESULT_RIL_NETWORK_ERR</code><br> 444 * <code>RESULT_RIL_INTERNAL_ERR</code><br> 445 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 446 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br> 447 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br> 448 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 449 * <code>RESULT_RIL_NO_RESOURCES</code><br> 450 * <code>RESULT_RIL_CANCELLED</code><br> 451 * <code>RESULT_RIL_SIM_ABSENT</code><br> 452 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 453 * <code>RESULT_RIL_ACCESS_BARRED</code><br> 454 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 455 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 456 * the sentIntent may include the extra "errorCode" containing a radio technology specific 457 * value, generally only useful for troubleshooting.<br> 458 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 459 * broadcast when the message is delivered to the recipient. The 460 * raw pdu of the status report is in the extended data ("pdu"). 461 * 462 * @throws IllegalArgumentException if destinationAddress or text are empty 463 */ sendTextMessage( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)464 public void sendTextMessage( 465 String destinationAddress, String scAddress, String text, 466 PendingIntent sentIntent, PendingIntent deliveryIntent) { 467 sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, 468 true /* persistMessage*/, getOpPackageName(), getAttributionTag(), 469 0L /* messageId */); 470 } 471 472 473 /** 474 * Send a text based SMS. Same as {@link #sendTextMessage( String destinationAddress, 475 * String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)}, but 476 * adds an optional messageId. 477 * @param messageId An id that uniquely identifies the message requested to be sent. 478 * Used for logging and diagnostics purposes. The id may be 0. 479 * 480 * @throws IllegalArgumentException if destinationAddress or text are empty 481 * 482 */ sendTextMessage( @onNull String destinationAddress, @Nullable String scAddress, @NonNull String text, @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent, long messageId)483 public void sendTextMessage( 484 @NonNull String destinationAddress, @Nullable String scAddress, @NonNull String text, 485 @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent, 486 long messageId) { 487 sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, 488 true /* persistMessage*/, getOpPackageName(), getAttributionTag(), 489 messageId); 490 } 491 492 /** 493 * Send a text based SMS with messaging options. 494 * 495 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 496 * manager on a multi-SIM device, this operation may fail sending the SMS message because no 497 * suitable default subscription could be found. In this case, if {@code sentIntent} is 498 * non-null, then the {@link PendingIntent} will be sent with an error code 499 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the 500 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions 501 * where this operation may fail. 502 * </p> 503 * 504 * @param destinationAddress the address to send the message to 505 * @param scAddress is the service center address or null to use 506 * the current default SMSC 507 * @param text the body of the message to send 508 * @param sentIntent if not NULL this <code>PendingIntent</code> is 509 * broadcast when the message is successfully sent, or failed. 510 * The result code will be <code>Activity.RESULT_OK</code> for success, 511 * or one of these errors:<br> 512 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 513 * <code>RESULT_ERROR_RADIO_OFF</code><br> 514 * <code>RESULT_ERROR_NULL_PDU</code><br> 515 * <code>RESULT_ERROR_NO_SERVICE</code><br> 516 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br> 517 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 518 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 519 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 520 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br> 521 * <code>RESULT_NETWORK_REJECT</code><br> 522 * <code>RESULT_INVALID_ARGUMENTS</code><br> 523 * <code>RESULT_INVALID_STATE</code><br> 524 * <code>RESULT_NO_MEMORY</code><br> 525 * <code>RESULT_INVALID_SMS_FORMAT</code><br> 526 * <code>RESULT_SYSTEM_ERROR</code><br> 527 * <code>RESULT_MODEM_ERROR</code><br> 528 * <code>RESULT_NETWORK_ERROR</code><br> 529 * <code>RESULT_ENCODING_ERROR</code><br> 530 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br> 531 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br> 532 * <code>RESULT_INTERNAL_ERROR</code><br> 533 * <code>RESULT_NO_RESOURCES</code><br> 534 * <code>RESULT_CANCELLED</code><br> 535 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br> 536 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br> 537 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 538 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br> 539 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 540 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 541 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br> 542 * <code>RESULT_REMOTE_EXCEPTION</code><br> 543 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br> 544 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 545 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 546 * <code>RESULT_RIL_NETWORK_REJECT</code><br> 547 * <code>RESULT_RIL_INVALID_STATE</code><br> 548 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br> 549 * <code>RESULT_RIL_NO_MEMORY</code><br> 550 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 551 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br> 552 * <code>RESULT_RIL_SYSTEM_ERR</code><br> 553 * <code>RESULT_RIL_ENCODING_ERR</code><br> 554 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 555 * <code>RESULT_RIL_MODEM_ERR</code><br> 556 * <code>RESULT_RIL_NETWORK_ERR</code><br> 557 * <code>RESULT_RIL_INTERNAL_ERR</code><br> 558 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 559 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br> 560 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br> 561 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 562 * <code>RESULT_RIL_NO_RESOURCES</code><br> 563 * <code>RESULT_RIL_CANCELLED</code><br> 564 * <code>RESULT_RIL_SIM_ABSENT</code><br> 565 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 566 * <code>RESULT_RIL_ACCESS_BARRED</code><br> 567 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 568 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 569 * the sentIntent may include the extra "errorCode" containing a radio technology specific 570 * value, generally only useful for troubleshooting.<br> 571 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 572 * broadcast when the message is delivered to the recipient. The 573 * raw pdu of the status report is in the extended data ("pdu"). 574 * @param priority Priority level of the message 575 * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 576 * --------------------------------- 577 * PRIORITY | Level of Priority 578 * --------------------------------- 579 * '00' | Normal 580 * '01' | Interactive 581 * '10' | Urgent 582 * '11' | Emergency 583 * ---------------------------------- 584 * Any Other values included Negative considered as Invalid Priority Indicator of the message. 585 * @param expectMore is a boolean to indicate the sending messages through same link or not. 586 * @param validityPeriod Validity Period of the message in mins. 587 * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. 588 * Validity Period(Minimum) -> 5 mins 589 * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). 590 * Any Other values included Negative considered as Invalid Validity Period of the message. 591 * 592 * @throws IllegalArgumentException if destinationAddress or text are empty 593 * {@hide} 594 */ 595 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) sendTextMessage( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, int priority, boolean expectMore, int validityPeriod)596 public void sendTextMessage( 597 String destinationAddress, String scAddress, String text, 598 PendingIntent sentIntent, PendingIntent deliveryIntent, 599 int priority, boolean expectMore, int validityPeriod) { 600 sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, 601 true /* persistMessage*/, priority, expectMore, validityPeriod); 602 } 603 sendTextMessageInternal(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, String packageName, String attributionTag, long messageId)604 private void sendTextMessageInternal(String destinationAddress, String scAddress, 605 String text, PendingIntent sentIntent, PendingIntent deliveryIntent, 606 boolean persistMessage, String packageName, String attributionTag, long messageId) { 607 if (TextUtils.isEmpty(destinationAddress)) { 608 throw new IllegalArgumentException("Invalid destinationAddress"); 609 } 610 611 if (TextUtils.isEmpty(text)) { 612 throw new IllegalArgumentException("Invalid message body"); 613 } 614 615 // We will only show the SMS disambiguation dialog in the case that the message is being 616 // persisted. This is for two reasons: 617 // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific 618 // subscription and require special permissions. These messages are usually not sent by 619 // the device user and should not have an SMS disambiguation dialog associated with them 620 // because the device user did not trigger them. 621 // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the SEND_SMS 622 // permission. If we call resolveSubscriptionForOperation from a carrier/OEM app that has 623 // the correct MODIFY_PHONE_STATE or carrier permissions, but no SEND_SMS, it will throw 624 // an incorrect SecurityException. 625 if (persistMessage) { 626 resolveSubscriptionForOperation(new SubscriptionResolverResult() { 627 @Override 628 public void onSuccess(int subId) { 629 ISms iSms = getISmsServiceOrThrow(); 630 try { 631 iSms.sendTextForSubscriber(subId, packageName, attributionTag, 632 destinationAddress, scAddress, text, sentIntent, deliveryIntent, 633 persistMessage, messageId); 634 } catch (RemoteException e) { 635 Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - " 636 + e.getMessage() + " " + formatCrossStackMessageId(messageId)); 637 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION); 638 } 639 } 640 641 @Override 642 public void onFailure() { 643 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP); 644 } 645 }); 646 } else { 647 // Not persisting the message, used by sendTextMessageWithoutPersisting() and is not 648 // visible to the user. 649 ISms iSms = getISmsServiceOrThrow(); 650 try { 651 iSms.sendTextForSubscriber(getSubscriptionId(), packageName, attributionTag, 652 destinationAddress, scAddress, text, sentIntent, deliveryIntent, 653 persistMessage, messageId); 654 } catch (RemoteException e) { 655 Log.e(TAG, "sendTextMessageInternal (no persist): Couldn't send SMS, exception - " 656 + e.getMessage() + " " + formatCrossStackMessageId(messageId)); 657 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION); 658 } 659 } 660 } 661 662 /** 663 * Send a text based SMS without writing it into the SMS Provider. 664 * 665 * <p> 666 * The message will be sent directly over the network and will not be visible in SMS 667 * applications. Intended for internal carrier use only. 668 * </p> 669 * 670 * <p>Requires Permission: Both {@link android.Manifest.permission#SEND_SMS} and 671 * {@link android.Manifest.permission#MODIFY_PHONE_STATE}, or that the calling app has carrier 672 * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), or that the calling app is 673 * the default IMS app (see 674 * {@link CarrierConfigManager#KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING}). 675 * </p> 676 * 677 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 678 * applications or the Telephony framework and will never trigger an SMS disambiguation 679 * dialog. If this method is called on a device that has multiple active subscriptions, this 680 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 681 * default subscription is defined, the subscription ID associated with this message will be 682 * INVALID, which will result in the SMS being sent on the subscription associated with logical 683 * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the 684 * correct subscription. 685 * </p> 686 * 687 * @see #sendTextMessage(String, String, String, PendingIntent, PendingIntent) 688 */ 689 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges 690 @RequiresPermission(allOf = { 691 android.Manifest.permission.MODIFY_PHONE_STATE, 692 android.Manifest.permission.SEND_SMS 693 }) sendTextMessageWithoutPersisting( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)694 public void sendTextMessageWithoutPersisting( 695 String destinationAddress, String scAddress, String text, 696 PendingIntent sentIntent, PendingIntent deliveryIntent) { 697 sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, 698 false /* persistMessage */, getOpPackageName(), 699 getAttributionTag(), 0L /* messageId */); 700 } 701 sendTextMessageInternal( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, int priority, boolean expectMore, int validityPeriod)702 private void sendTextMessageInternal( 703 String destinationAddress, String scAddress, String text, 704 PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, 705 int priority, boolean expectMore, int validityPeriod) { 706 if (TextUtils.isEmpty(destinationAddress)) { 707 throw new IllegalArgumentException("Invalid destinationAddress"); 708 } 709 710 if (TextUtils.isEmpty(text)) { 711 throw new IllegalArgumentException("Invalid message body"); 712 } 713 714 if (priority < 0x00 || priority > 0x03) { 715 Log.e(TAG, "Invalid Priority " + priority); 716 priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED; 717 } 718 719 if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) { 720 Log.e(TAG, "Invalid Validity Period " + validityPeriod); 721 validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED; 722 } 723 724 final int finalPriority = priority; 725 final int finalValidity = validityPeriod; 726 // We will only show the SMS disambiguation dialog in the case that the message is being 727 // persisted. This is for two reasons: 728 // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific 729 // subscription and require special permissions. These messages are usually not sent by 730 // the device user and should not have an SMS disambiguation dialog associated with them 731 // because the device user did not trigger them. 732 // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the SEND_SMS 733 // permission. If we call resolveSubscriptionForOperation from a carrier/OEM app that has 734 // the correct MODIFY_PHONE_STATE or carrier permissions, but no SEND_SMS, it will throw 735 // an incorrect SecurityException. 736 if (persistMessage) { 737 resolveSubscriptionForOperation(new SubscriptionResolverResult() { 738 @Override 739 public void onSuccess(int subId) { 740 try { 741 ISms iSms = getISmsServiceOrThrow(); 742 if (iSms != null) { 743 iSms.sendTextForSubscriberWithOptions(subId, 744 null, null, destinationAddress, 745 scAddress, 746 text, sentIntent, deliveryIntent, persistMessage, finalPriority, 747 expectMore, finalValidity); 748 } 749 } catch (RemoteException e) { 750 Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - " 751 + e.getMessage()); 752 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION); 753 } 754 } 755 756 @Override 757 public void onFailure() { 758 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP); 759 } 760 }); 761 } else { 762 try { 763 ISms iSms = getISmsServiceOrThrow(); 764 if (iSms != null) { 765 iSms.sendTextForSubscriberWithOptions(getSubscriptionId(), 766 null, null, destinationAddress, 767 scAddress, 768 text, sentIntent, deliveryIntent, persistMessage, finalPriority, 769 expectMore, finalValidity); 770 } 771 } catch (RemoteException e) { 772 Log.e(TAG, "sendTextMessageInternal(no persist): Couldn't send SMS, exception - " 773 + e.getMessage()); 774 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION); 775 } 776 } 777 } 778 779 /** 780 * 781 * Inject an SMS PDU into the android application framework. 782 * 783 * <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier 784 * privileges per {@link android.telephony.TelephonyManager#hasCarrierPrivileges}. 785 * 786 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 787 * applications or the Telephony framework and will never trigger an SMS disambiguation 788 * dialog. If this method is called on a device that has multiple active subscriptions, this 789 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 790 * default subscription is defined, the subscription ID associated with this message will be 791 * INVALID, which will result in the SMS being injected on the subscription associated with 792 * logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is 793 * delivered to the correct subscription. 794 * </p> 795 * 796 * @param pdu is the byte array of pdu to be injected into android application framework 797 * @param format is the format of SMS pdu ({@link SmsMessage#FORMAT_3GPP} or 798 * {@link SmsMessage#FORMAT_3GPP2}) 799 * @param receivedIntent if not NULL this <code>PendingIntent</code> is 800 * broadcast when the message is successfully received by the 801 * android application framework, or failed. This intent is broadcasted at 802 * the same time an SMS received from radio is acknowledged back. 803 * The result code will be {@link android.provider.Telephony.Sms.Intents#RESULT_SMS_HANDLED} 804 * for success, or {@link android.provider.Telephony.Sms.Intents#RESULT_SMS_GENERIC_ERROR} or 805 * {@link #RESULT_REMOTE_EXCEPTION} for error. 806 * 807 * @throws IllegalArgumentException if the format is invalid. 808 */ injectSmsPdu( byte[] pdu, @SmsMessage.Format String format, PendingIntent receivedIntent)809 public void injectSmsPdu( 810 byte[] pdu, @SmsMessage.Format String format, PendingIntent receivedIntent) { 811 if (!format.equals(SmsMessage.FORMAT_3GPP) && !format.equals(SmsMessage.FORMAT_3GPP2)) { 812 // Format must be either 3gpp or 3gpp2. 813 throw new IllegalArgumentException( 814 "Invalid pdu format. format must be either 3gpp or 3gpp2"); 815 } 816 try { 817 ISms iSms = TelephonyManager.getSmsService(); 818 if (iSms != null) { 819 iSms.injectSmsPduForSubscriber( 820 getSubscriptionId(), pdu, format, receivedIntent); 821 } 822 } catch (RemoteException ex) { 823 try { 824 if (receivedIntent != null) { 825 receivedIntent.send(RESULT_REMOTE_EXCEPTION); 826 } 827 } catch (PendingIntent.CanceledException cx) { 828 // Don't worry about it, we do not need to notify the caller if this is the case. 829 } 830 } 831 } 832 833 /** 834 * Divide a message text into several fragments, none bigger than the maximum SMS message size. 835 * 836 * @param text the original message. Must not be null. 837 * @return an <code>ArrayList</code> of strings that, in order, comprise the original message. 838 * @throws IllegalArgumentException if text is null. 839 */ divideMessage(String text)840 public ArrayList<String> divideMessage(String text) { 841 if (null == text) { 842 throw new IllegalArgumentException("text is null"); 843 } 844 return SmsMessage.fragmentText(text, getSubscriptionId()); 845 } 846 847 /** 848 * Send a multi-part text based SMS. The callee should have already 849 * divided the message into correctly sized parts by calling 850 * <code>divideMessage</code>. 851 * 852 * <p class="note"><strong>Note:</strong> Using this method requires that your app has the 853 * {@link android.Manifest.permission#SEND_SMS} permission.</p> 854 * 855 * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if 856 * <em>and only if</em> an app is not selected as the default SMS app, the system automatically 857 * writes messages sent using this method to the SMS Provider (the default SMS app is always 858 * responsible for writing its sent messages to the SMS Provider). For information about 859 * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p> 860 * 861 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 862 * manager on a multi-SIM device, this operation may fail sending the SMS message because no 863 * suitable default subscription could be found. In this case, if {@code sentIntent} is 864 * non-null, then the {@link PendingIntent} will be sent with an error code 865 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the 866 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions 867 * where this operation may fail. 868 * </p> 869 * 870 * @param destinationAddress the address to send the message to 871 * @param scAddress is the service center address or null to use 872 * the current default SMSC 873 * @param parts an <code>ArrayList</code> of strings that, in order, 874 * comprise the original message 875 * @param sentIntents if not null, an <code>ArrayList</code> of 876 * <code>PendingIntent</code>s (one for each message part) that is 877 * broadcast when the corresponding message part has been sent. 878 * The result code will be <code>Activity.RESULT_OK</code> for success, 879 * or one of these errors:<br> 880 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 881 * <code>RESULT_ERROR_RADIO_OFF</code><br> 882 * <code>RESULT_ERROR_NULL_PDU</code><br> 883 * <code>RESULT_ERROR_NO_SERVICE</code><br> 884 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br> 885 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 886 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 887 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 888 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br> 889 * <code>RESULT_NETWORK_REJECT</code><br> 890 * <code>RESULT_INVALID_ARGUMENTS</code><br> 891 * <code>RESULT_INVALID_STATE</code><br> 892 * <code>RESULT_NO_MEMORY</code><br> 893 * <code>RESULT_INVALID_SMS_FORMAT</code><br> 894 * <code>RESULT_SYSTEM_ERROR</code><br> 895 * <code>RESULT_MODEM_ERROR</code><br> 896 * <code>RESULT_NETWORK_ERROR</code><br> 897 * <code>RESULT_ENCODING_ERROR</code><br> 898 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br> 899 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br> 900 * <code>RESULT_INTERNAL_ERROR</code><br> 901 * <code>RESULT_NO_RESOURCES</code><br> 902 * <code>RESULT_CANCELLED</code><br> 903 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br> 904 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br> 905 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 906 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br> 907 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 908 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 909 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br> 910 * <code>RESULT_REMOTE_EXCEPTION</code><br> 911 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br> 912 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 913 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 914 * <code>RESULT_RIL_NETWORK_REJECT</code><br> 915 * <code>RESULT_RIL_INVALID_STATE</code><br> 916 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br> 917 * <code>RESULT_RIL_NO_MEMORY</code><br> 918 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 919 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br> 920 * <code>RESULT_RIL_SYSTEM_ERR</code><br> 921 * <code>RESULT_RIL_ENCODING_ERR</code><br> 922 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 923 * <code>RESULT_RIL_MODEM_ERR</code><br> 924 * <code>RESULT_RIL_NETWORK_ERR</code><br> 925 * <code>RESULT_RIL_INTERNAL_ERR</code><br> 926 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 927 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br> 928 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br> 929 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 930 * <code>RESULT_RIL_NO_RESOURCES</code><br> 931 * <code>RESULT_RIL_CANCELLED</code><br> 932 * <code>RESULT_RIL_SIM_ABSENT</code><br> 933 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 934 * <code>RESULT_RIL_ACCESS_BARRED</code><br> 935 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 936 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 937 * the sentIntent may include the extra "errorCode" containing a radio technology specific 938 * value, generally only useful for troubleshooting.<br> 939 * @param deliveryIntents if not null, an <code>ArrayList</code> of 940 * <code>PendingIntent</code>s (one for each message part) that is 941 * broadcast when the corresponding message part has been delivered 942 * to the recipient. The raw pdu of the status report is in the 943 * extended data ("pdu"). 944 * 945 * @throws IllegalArgumentException if destinationAddress or data are empty 946 */ sendMultipartTextMessage( String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents)947 public void sendMultipartTextMessage( 948 String destinationAddress, String scAddress, ArrayList<String> parts, 949 ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { 950 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, 951 deliveryIntents, true /* persistMessage*/, getOpPackageName(), 952 getAttributionTag(), 0L /* messageId */); 953 } 954 955 /** 956 * Send a multi-part text based SMS. Same as #sendMultipartTextMessage(String, String, 957 * ArrayList, ArrayList, ArrayList), but adds an optional messageId. 958 * @param messageId An id that uniquely identifies the message requested to be sent. 959 * Used for logging and diagnostics purposes. The id may be 0. 960 * 961 * @throws IllegalArgumentException if destinationAddress or data are empty 962 * 963 */ sendMultipartTextMessage( @onNull String destinationAddress, @Nullable String scAddress, @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, @Nullable List<PendingIntent> deliveryIntents, long messageId)964 public void sendMultipartTextMessage( 965 @NonNull String destinationAddress, @Nullable String scAddress, 966 @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, 967 @Nullable List<PendingIntent> deliveryIntents, long messageId) { 968 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, 969 deliveryIntents, true /* persistMessage*/, getOpPackageName(), 970 getAttributionTag(), messageId); 971 } 972 973 /** 974 * Similar method as #sendMultipartTextMessage(String, String, ArrayList, ArrayList, ArrayList) 975 * With an additional argument. 976 * 977 * <p class="note"><strong>Note:</strong> This method is intended for internal use the Telephony 978 * framework and will never trigger an SMS disambiguation dialog. If this method is called on a 979 * device that has multiple active subscriptions, this {@link SmsManager} instance has been 980 * created with {@link #getDefault()}, and no user-defined default subscription is defined, the 981 * subscription ID associated with this message will be INVALID, which will result in the SMS 982 * being sent on the subscription associated with logical slot 0. Use 983 * {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the correct 984 * subscription. 985 * </p> 986 * 987 * @param packageName serves as the default package name if the package name that is 988 * associated with the user id is null. 989 */ sendMultipartTextMessage( @onNull String destinationAddress, @Nullable String scAddress, @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName, @Nullable String attributionTag)990 public void sendMultipartTextMessage( 991 @NonNull String destinationAddress, @Nullable String scAddress, 992 @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, 993 @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName, 994 @Nullable String attributionTag) { 995 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, 996 deliveryIntents, true /* persistMessage*/, packageName, attributionTag, 997 0L /* messageId */); 998 } 999 sendMultipartTextMessageInternal( String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessage, String packageName, @Nullable String attributionTag, long messageId)1000 private void sendMultipartTextMessageInternal( 1001 String destinationAddress, String scAddress, List<String> parts, 1002 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, 1003 boolean persistMessage, String packageName, @Nullable String attributionTag, 1004 long messageId) { 1005 if (TextUtils.isEmpty(destinationAddress)) { 1006 throw new IllegalArgumentException("Invalid destinationAddress"); 1007 } 1008 if (parts == null || parts.size() < 1) { 1009 throw new IllegalArgumentException("Invalid message body"); 1010 } 1011 1012 if (parts.size() > 1) { 1013 // We will only show the SMS disambiguation dialog in the case that the message is being 1014 // persisted. This is for two reasons: 1015 // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific 1016 // subscription and require special permissions. These messages are usually not sent 1017 // by the device user and should not have an SMS disambiguation dialog associated 1018 // with them because the device user did not trigger them. 1019 // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the 1020 // SEND_SMS permission. If we call resolveSubscriptionForOperation from a carrier/OEM 1021 // app that has the correct MODIFY_PHONE_STATE or carrier permissions, but no 1022 // SEND_SMS, it will throw an incorrect SecurityException. 1023 if (persistMessage) { 1024 resolveSubscriptionForOperation(new SubscriptionResolverResult() { 1025 @Override 1026 public void onSuccess(int subId) { 1027 try { 1028 ISms iSms = getISmsServiceOrThrow(); 1029 iSms.sendMultipartTextForSubscriber(subId, packageName, attributionTag, 1030 destinationAddress, scAddress, parts, sentIntents, 1031 deliveryIntents, persistMessage, messageId); 1032 } catch (RemoteException e) { 1033 Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - " 1034 + e.getMessage() + " " + formatCrossStackMessageId(messageId)); 1035 notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION); 1036 } 1037 } 1038 1039 @Override 1040 public void onFailure() { 1041 notifySmsError(sentIntents, RESULT_NO_DEFAULT_SMS_APP); 1042 } 1043 }); 1044 } else { 1045 // Called by apps that are not user facing, don't show disambiguation dialog. 1046 try { 1047 ISms iSms = getISmsServiceOrThrow(); 1048 if (iSms != null) { 1049 iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName, 1050 attributionTag, destinationAddress, scAddress, parts, sentIntents, 1051 deliveryIntents, persistMessage, messageId); 1052 } 1053 } catch (RemoteException e) { 1054 Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - " 1055 + e.getMessage() + " " + formatCrossStackMessageId(messageId)); 1056 notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION); 1057 } 1058 } 1059 } else { 1060 PendingIntent sentIntent = null; 1061 PendingIntent deliveryIntent = null; 1062 if (sentIntents != null && sentIntents.size() > 0) { 1063 sentIntent = sentIntents.get(0); 1064 } 1065 if (deliveryIntents != null && deliveryIntents.size() > 0) { 1066 deliveryIntent = deliveryIntents.get(0); 1067 } 1068 sendTextMessageInternal(destinationAddress, scAddress, parts.get(0), 1069 sentIntent, deliveryIntent, true, packageName, attributionTag, messageId); 1070 } 1071 } 1072 1073 /** 1074 * Send a multi-part text based SMS without writing it into the SMS Provider. 1075 * 1076 * <p> 1077 * If this method is called on a device with multiple active subscriptions, this 1078 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 1079 * default subscription is defined, the subscription ID associated with this message will be 1080 * INVALID, which will result in the SMS sent on the subscription associated with slot 1081 * 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent using the 1082 * correct subscription. 1083 * </p> 1084 * 1085 * <p>Requires Permission: 1086 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier 1087 * privileges. 1088 * </p> 1089 * 1090 * @see #sendMultipartTextMessage(String, String, ArrayList, ArrayList, ArrayList) 1091 * @hide 1092 **/ 1093 @SystemApi 1094 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) sendMultipartTextMessageWithoutPersisting( String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)1095 public void sendMultipartTextMessageWithoutPersisting( 1096 String destinationAddress, String scAddress, List<String> parts, 1097 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { 1098 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, 1099 deliveryIntents, false /* persistMessage*/, getOpPackageName(), 1100 getAttributionTag(), 0L /* messageId */); 1101 } 1102 1103 /** 1104 * Send a multi-part text based SMS with messaging options. The callee should have already 1105 * divided the message into correctly sized parts by calling 1106 * <code>divideMessage</code>. 1107 * 1108 * <p class="note"><strong>Note:</strong> Using this method requires that your app has the 1109 * {@link android.Manifest.permission#SEND_SMS} permission.</p> 1110 * 1111 * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if 1112 * <em>and only if</em> an app is not selected as the default SMS app, the system automatically 1113 * writes messages sent using this method to the SMS Provider (the default SMS app is always 1114 * responsible for writing its sent messages to the SMS Provider). For information about 1115 * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p> 1116 * 1117 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 1118 * manager on a multi-SIM device, this operation may fail sending the SMS message because no 1119 * suitable default subscription could be found. In this case, if {@code sentIntent} is 1120 * non-null, then the {@link PendingIntent} will be sent with an error code 1121 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the 1122 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions 1123 * where this operation may fail. 1124 * </p> 1125 * 1126 * @param destinationAddress the address to send the message to 1127 * @param scAddress is the service center address or null to use 1128 * the current default SMSC 1129 * @param parts an <code>ArrayList</code> of strings that, in order, 1130 * comprise the original message 1131 * @param sentIntents if not null, an <code>ArrayList</code> of 1132 * <code>PendingIntent</code>s (one for each message part) that is 1133 * broadcast when the corresponding message part has been sent. 1134 * The result code will be <code>Activity.RESULT_OK</code> for success, 1135 * or one of these errors:<br> 1136 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 1137 * <code>RESULT_ERROR_RADIO_OFF</code><br> 1138 * <code>RESULT_ERROR_NULL_PDU</code><br> 1139 * <code>RESULT_ERROR_NO_SERVICE</code><br> 1140 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br> 1141 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 1142 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 1143 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 1144 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br> 1145 * <code>RESULT_NETWORK_REJECT</code><br> 1146 * <code>RESULT_INVALID_ARGUMENTS</code><br> 1147 * <code>RESULT_INVALID_STATE</code><br> 1148 * <code>RESULT_NO_MEMORY</code><br> 1149 * <code>RESULT_INVALID_SMS_FORMAT</code><br> 1150 * <code>RESULT_SYSTEM_ERROR</code><br> 1151 * <code>RESULT_MODEM_ERROR</code><br> 1152 * <code>RESULT_NETWORK_ERROR</code><br> 1153 * <code>RESULT_ENCODING_ERROR</code><br> 1154 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br> 1155 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br> 1156 * <code>RESULT_INTERNAL_ERROR</code><br> 1157 * <code>RESULT_NO_RESOURCES</code><br> 1158 * <code>RESULT_CANCELLED</code><br> 1159 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br> 1160 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br> 1161 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 1162 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br> 1163 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 1164 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 1165 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br> 1166 * <code>RESULT_REMOTE_EXCEPTION</code><br> 1167 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br> 1168 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 1169 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 1170 * <code>RESULT_RIL_NETWORK_REJECT</code><br> 1171 * <code>RESULT_RIL_INVALID_STATE</code><br> 1172 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br> 1173 * <code>RESULT_RIL_NO_MEMORY</code><br> 1174 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 1175 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br> 1176 * <code>RESULT_RIL_SYSTEM_ERR</code><br> 1177 * <code>RESULT_RIL_ENCODING_ERR</code><br> 1178 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 1179 * <code>RESULT_RIL_MODEM_ERR</code><br> 1180 * <code>RESULT_RIL_NETWORK_ERR</code><br> 1181 * <code>RESULT_RIL_INTERNAL_ERR</code><br> 1182 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 1183 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br> 1184 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br> 1185 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 1186 * <code>RESULT_RIL_NO_RESOURCES</code><br> 1187 * <code>RESULT_RIL_CANCELLED</code><br> 1188 * <code>RESULT_RIL_SIM_ABSENT</code><br> 1189 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 1190 * <code>RESULT_RIL_ACCESS_BARRED</code><br> 1191 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 1192 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 1193 * the sentIntent may include the extra "errorCode" containing a radio technology specific 1194 * value, generally only useful for troubleshooting.<br> 1195 * @param deliveryIntents if not null, an <code>ArrayList</code> of 1196 * <code>PendingIntent</code>s (one for each message part) that is 1197 * broadcast when the corresponding message part has been delivered 1198 * to the recipient. The raw pdu of the status report is in the 1199 * extended data ("pdu"). 1200 * @param priority Priority level of the message 1201 * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 1202 * --------------------------------- 1203 * PRIORITY | Level of Priority 1204 * --------------------------------- 1205 * '00' | Normal 1206 * '01' | Interactive 1207 * '10' | Urgent 1208 * '11' | Emergency 1209 * ---------------------------------- 1210 * Any Other values included Negative considered as Invalid Priority Indicator of the message. 1211 * @param expectMore is a boolean to indicate the sending messages through same link or not. 1212 * @param validityPeriod Validity Period of the message in mins. 1213 * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. 1214 * Validity Period(Minimum) -> 5 mins 1215 * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). 1216 * Any Other values included Negative considered as Invalid Validity Period of the message. 1217 * 1218 * @throws IllegalArgumentException if destinationAddress or data are empty 1219 * {@hide} 1220 */ 1221 @UnsupportedAppUsage sendMultipartTextMessage( String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents, int priority, boolean expectMore, int validityPeriod)1222 public void sendMultipartTextMessage( 1223 String destinationAddress, String scAddress, ArrayList<String> parts, 1224 ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents, 1225 int priority, boolean expectMore, int validityPeriod) { 1226 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, 1227 deliveryIntents, true /* persistMessage*/, priority, expectMore, 1228 validityPeriod); 1229 } 1230 sendMultipartTextMessageInternal( String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessage, int priority, boolean expectMore, int validityPeriod)1231 private void sendMultipartTextMessageInternal( 1232 String destinationAddress, String scAddress, List<String> parts, 1233 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, 1234 boolean persistMessage, int priority, boolean expectMore, int validityPeriod) { 1235 if (TextUtils.isEmpty(destinationAddress)) { 1236 throw new IllegalArgumentException("Invalid destinationAddress"); 1237 } 1238 if (parts == null || parts.size() < 1) { 1239 throw new IllegalArgumentException("Invalid message body"); 1240 } 1241 1242 if (priority < 0x00 || priority > 0x03) { 1243 Log.e(TAG, "Invalid Priority " + priority); 1244 priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED; 1245 } 1246 1247 if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) { 1248 Log.e(TAG, "Invalid Validity Period " + validityPeriod); 1249 validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED; 1250 } 1251 1252 if (parts.size() > 1) { 1253 final int finalPriority = priority; 1254 final int finalValidity = validityPeriod; 1255 if (persistMessage) { 1256 resolveSubscriptionForOperation(new SubscriptionResolverResult() { 1257 @Override 1258 public void onSuccess(int subId) { 1259 try { 1260 ISms iSms = getISmsServiceOrThrow(); 1261 if (iSms != null) { 1262 iSms.sendMultipartTextForSubscriberWithOptions(subId, 1263 null, null, destinationAddress, 1264 scAddress, parts, sentIntents, deliveryIntents, 1265 persistMessage, finalPriority, expectMore, finalValidity); 1266 } 1267 } catch (RemoteException e) { 1268 Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - " 1269 + e.getMessage()); 1270 notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION); 1271 } 1272 } 1273 1274 @Override 1275 public void onFailure() { 1276 notifySmsError(sentIntents, RESULT_NO_DEFAULT_SMS_APP); 1277 } 1278 }); 1279 } else { 1280 // Sent by apps that are not user visible, so don't show SIM disambiguation dialog. 1281 try { 1282 ISms iSms = getISmsServiceOrThrow(); 1283 if (iSms != null) { 1284 iSms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(), 1285 null, null, destinationAddress, 1286 scAddress, parts, sentIntents, deliveryIntents, 1287 persistMessage, finalPriority, expectMore, finalValidity); 1288 } 1289 } catch (RemoteException e) { 1290 Log.e(TAG, "sendMultipartTextMessageInternal (no persist): Couldn't send SMS - " 1291 + e.getMessage()); 1292 notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION); 1293 } 1294 } 1295 } else { 1296 PendingIntent sentIntent = null; 1297 PendingIntent deliveryIntent = null; 1298 if (sentIntents != null && sentIntents.size() > 0) { 1299 sentIntent = sentIntents.get(0); 1300 } 1301 if (deliveryIntents != null && deliveryIntents.size() > 0) { 1302 deliveryIntent = deliveryIntents.get(0); 1303 } 1304 sendTextMessageInternal(destinationAddress, scAddress, parts.get(0), 1305 sentIntent, deliveryIntent, persistMessage, priority, expectMore, 1306 validityPeriod); 1307 } 1308 } 1309 1310 /** 1311 * Send a data based SMS to a specific application port. 1312 * 1313 * <p class="note"><strong>Note:</strong> Using this method requires that your app has the 1314 * {@link android.Manifest.permission#SEND_SMS} permission.</p> 1315 * 1316 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 1317 * manager on a multi-SIM device, this operation may fail sending the SMS message because no 1318 * suitable default subscription could be found. In this case, if {@code sentIntent} is 1319 * non-null, then the {@link PendingIntent} will be sent with an error code 1320 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the 1321 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions 1322 * where this operation may fail. 1323 * </p> 1324 * 1325 * @param destinationAddress the address to send the message to 1326 * @param scAddress is the service center address or null to use 1327 * the current default SMSC 1328 * @param destinationPort the port to deliver the message to 1329 * @param data the body of the message to send 1330 * @param sentIntent if not NULL this <code>PendingIntent</code> is 1331 * broadcast when the message is successfully sent, or failed. 1332 * The result code will be <code>Activity.RESULT_OK</code> for success, 1333 * or one of these errors:<br> 1334 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 1335 * <code>RESULT_ERROR_RADIO_OFF</code><br> 1336 * <code>RESULT_ERROR_NULL_PDU</code><br> 1337 * <code>RESULT_ERROR_NO_SERVICE</code><br> 1338 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br> 1339 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 1340 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 1341 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 1342 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br> 1343 * <code>RESULT_NETWORK_REJECT</code><br> 1344 * <code>RESULT_INVALID_ARGUMENTS</code><br> 1345 * <code>RESULT_INVALID_STATE</code><br> 1346 * <code>RESULT_NO_MEMORY</code><br> 1347 * <code>RESULT_INVALID_SMS_FORMAT</code><br> 1348 * <code>RESULT_SYSTEM_ERROR</code><br> 1349 * <code>RESULT_MODEM_ERROR</code><br> 1350 * <code>RESULT_NETWORK_ERROR</code><br> 1351 * <code>RESULT_ENCODING_ERROR</code><br> 1352 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br> 1353 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br> 1354 * <code>RESULT_INTERNAL_ERROR</code><br> 1355 * <code>RESULT_NO_RESOURCES</code><br> 1356 * <code>RESULT_CANCELLED</code><br> 1357 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br> 1358 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br> 1359 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 1360 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br> 1361 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 1362 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 1363 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br> 1364 * <code>RESULT_REMOTE_EXCEPTION</code><br> 1365 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br> 1366 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 1367 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 1368 * <code>RESULT_RIL_NETWORK_REJECT</code><br> 1369 * <code>RESULT_RIL_INVALID_STATE</code><br> 1370 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br> 1371 * <code>RESULT_RIL_NO_MEMORY</code><br> 1372 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 1373 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br> 1374 * <code>RESULT_RIL_SYSTEM_ERR</code><br> 1375 * <code>RESULT_RIL_ENCODING_ERR</code><br> 1376 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 1377 * <code>RESULT_RIL_MODEM_ERR</code><br> 1378 * <code>RESULT_RIL_NETWORK_ERR</code><br> 1379 * <code>RESULT_RIL_INTERNAL_ERR</code><br> 1380 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 1381 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br> 1382 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br> 1383 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 1384 * <code>RESULT_RIL_NO_RESOURCES</code><br> 1385 * <code>RESULT_RIL_CANCELLED</code><br> 1386 * <code>RESULT_RIL_SIM_ABSENT</code><br> 1387 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 1388 * <code>RESULT_RIL_ACCESS_BARRED</code><br> 1389 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 1390 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 1391 * the sentIntent may include the extra "errorCode" containing a radio technology specific 1392 * value, generally only useful for troubleshooting.<br> 1393 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 1394 * broadcast when the message is delivered to the recipient. The 1395 * raw pdu of the status report is in the extended data ("pdu"). 1396 * 1397 * @throws IllegalArgumentException if destinationAddress or data are empty 1398 */ sendDataMessage( String destinationAddress, String scAddress, short destinationPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)1399 public void sendDataMessage( 1400 String destinationAddress, String scAddress, short destinationPort, 1401 byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 1402 if (TextUtils.isEmpty(destinationAddress)) { 1403 throw new IllegalArgumentException("Invalid destinationAddress"); 1404 } 1405 1406 if (data == null || data.length == 0) { 1407 throw new IllegalArgumentException("Invalid message data"); 1408 } 1409 1410 resolveSubscriptionForOperation(new SubscriptionResolverResult() { 1411 @Override 1412 public void onSuccess(int subId) { 1413 try { 1414 ISms iSms = getISmsServiceOrThrow(); 1415 iSms.sendDataForSubscriber(subId, null, null, destinationAddress, scAddress, 1416 destinationPort & 0xFFFF, data, sentIntent, deliveryIntent); 1417 } catch (RemoteException e) { 1418 Log.e(TAG, "sendDataMessage: Couldn't send SMS - Exception: " + e.getMessage()); 1419 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION); 1420 } 1421 } 1422 @Override 1423 public void onFailure() { 1424 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP); 1425 } 1426 }); 1427 } 1428 1429 /** 1430 * Get the SmsManager associated with the default subscription id. The instance will always be 1431 * associated with the default subscription id, even if the default subscription id changes. 1432 * 1433 * <p class="note"><strong>Note:</strong> For devices that support multiple active subscriptions 1434 * at a time, SmsManager will track the subscription set by the user as the default SMS 1435 * subscription. If the user has not set a default, {@link SmsManager} may 1436 * start an activity to kick off a subscription disambiguation dialog. Most operations will not 1437 * complete until the user has chosen the subscription that will be associated with the 1438 * operation. If the user cancels the dialog without choosing a subscription, one of the 1439 * following will happen, depending on the target SDK version of the application. For 1440 * compatibility purposes, if the target SDK level is <= 28, telephony will still send the SMS 1441 * over the first available subscription. If the target SDK level is > 28, the operation will 1442 * fail to complete. 1443 * </p> 1444 * 1445 * <p class="note"><strong>Note:</strong> If this method is used to perform an operation on a 1446 * device that has multiple active subscriptions, the user has not set a default SMS 1447 * subscription, and the operation is being performed while the application is not in the 1448 * foreground, the SMS disambiguation dialog will not be shown. The result of the operation will 1449 * conclude as if the user cancelled the disambiguation dialog and the operation will finish as 1450 * outlined above, depending on the target SDK version of the calling application. It is safer 1451 * to use {@link #getSmsManagerForSubscriptionId(int)} if the application will perform the 1452 * operation while in the background because this can cause unpredictable results, such as the 1453 * operation being sent over the wrong subscription or failing completely, depending on the 1454 * user's default SMS subscription setting. 1455 * </p> 1456 * 1457 * @return the {@link SmsManager} associated with the default subscription id. 1458 * 1459 * @see SubscriptionManager#getDefaultSmsSubscriptionId() 1460 * 1461 * @deprecated Use {@link Context#getSystemService Context.getSystemService(SmsManager.class)} 1462 * instead 1463 */ 1464 @Deprecated getDefault()1465 public static SmsManager getDefault() { 1466 return DEFAULT_INSTANCE; 1467 } 1468 1469 /** 1470 * Get the instance of the SmsManager associated with a particular context and subscription ID. 1471 * 1472 * @param context The context the manager belongs to 1473 * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager} 1474 * 1475 * @return the instance of the SmsManager associated with subscription 1476 * 1477 * @hide 1478 */ getSmsManagerForContextAndSubscriptionId( @ullable Context context, int subId)1479 public static @NonNull SmsManager getSmsManagerForContextAndSubscriptionId( 1480 @Nullable Context context, int subId) { 1481 synchronized(sLockObject) { 1482 Pair<Context, Integer> key = new Pair<>(context, subId); 1483 1484 SmsManager smsManager = sSubInstances.get(key); 1485 if (smsManager == null) { 1486 smsManager = new SmsManager(context, subId); 1487 sSubInstances.put(key, smsManager); 1488 } 1489 return smsManager; 1490 } 1491 } 1492 1493 /** 1494 * Get the instance of the SmsManager associated with a particular subscription ID. 1495 * 1496 * <p class="note"><strong>Note:</strong> Constructing an {@link SmsManager} in this manner will 1497 * never cause an SMS disambiguation dialog to appear, unlike {@link #getDefault()}. 1498 * </p> 1499 * 1500 * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager} 1501 * @return the instance of the SmsManager associated with subscription 1502 * 1503 * @see SubscriptionManager#getActiveSubscriptionInfoList() 1504 * @see SubscriptionManager#getDefaultSmsSubscriptionId() 1505 * @deprecated Use {@link Context#getSystemService Context.getSystemService(SmsManager.class)} 1506 * .{@link #createForSubscriptionId createForSubscriptionId(subId)} instead 1507 */ 1508 @Deprecated getSmsManagerForSubscriptionId(int subId)1509 public static SmsManager getSmsManagerForSubscriptionId(int subId) { 1510 return getSmsManagerForContextAndSubscriptionId(null, subId); 1511 } 1512 1513 /** 1514 * Get the instance of the SmsManager associated with a particular subscription ID. 1515 * 1516 * <p class="note"><strong>Note:</strong> Constructing an {@link SmsManager} in this manner will 1517 * never cause an SMS disambiguation dialog to appear, unlike {@link #getDefault()}. 1518 * </p> 1519 * 1520 * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager} 1521 * @return the instance of the SmsManager associated with subscription 1522 * 1523 * @see SubscriptionManager#getActiveSubscriptionInfoList() 1524 * @see SubscriptionManager#getDefaultSmsSubscriptionId() 1525 */ createForSubscriptionId(int subId)1526 public @NonNull SmsManager createForSubscriptionId(int subId) { 1527 return getSmsManagerForContextAndSubscriptionId(mContext, subId); 1528 } 1529 SmsManager(@ullable Context context, int subId)1530 private SmsManager(@Nullable Context context, int subId) { 1531 mContext = context; 1532 mSubId = subId; 1533 } 1534 1535 /** 1536 * Get the associated subscription id. If the instance was returned by {@link #getDefault()}, 1537 * then this method may return different values at different points in time (if the user 1538 * changes the default subscription id). 1539 * 1540 * <p class="note"><strong>Note:</strong> This method used to display a disambiguation dialog to 1541 * the user asking them to choose a default subscription to send SMS messages over if they 1542 * haven't chosen yet. Starting in API level 29, we allow the user to not have a default set as 1543 * a valid option for the default SMS subscription on multi-SIM devices. We no longer show the 1544 * disambiguation dialog and return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if the 1545 * device has multiple active subscriptions and no default is set. 1546 * </p> 1547 * 1548 * @return associated subscription ID or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if 1549 * the default subscription id cannot be determined or the device has multiple active 1550 * subscriptions and and no default is set ("ask every time") by the user. 1551 */ getSubscriptionId()1552 public int getSubscriptionId() { 1553 try { 1554 return (mSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) 1555 ? getISmsServiceOrThrow().getPreferredSmsSubscription() : mSubId; 1556 } catch (RemoteException e) { 1557 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1558 } 1559 } 1560 1561 /** 1562 * Resolves the subscription id to use for the associated operation if 1563 * {@link #getSubscriptionId()} returns {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. 1564 * 1565 * If app targets API level 28 or below and they are either sending the SMS from the background 1566 * or the device has more than one active subscription available and no default is set, we will 1567 * use the first logical slot to send the SMS and possibly fail later in the SMS sending 1568 * process. 1569 * 1570 * Regardless of the API level, if the app is the foreground app, then we will show the SMS 1571 * disambiguation dialog. If the app is in the background and tries to perform an operation, we 1572 * will not show the disambiguation dialog. 1573 * 1574 * See {@link #getDefault()} for a detailed explanation of how this method operates. 1575 * 1576 * @param resolverResult The callback that will be called when the subscription is resolved or 1577 * fails to be resolved. 1578 */ resolveSubscriptionForOperation(SubscriptionResolverResult resolverResult)1579 private void resolveSubscriptionForOperation(SubscriptionResolverResult resolverResult) { 1580 int subId = getSubscriptionId(); 1581 boolean isSmsSimPickActivityNeeded = false; 1582 try { 1583 ISms iSms = getISmsService(); 1584 if (iSms != null) { 1585 // Determines if the SMS SIM pick activity should be shown. This is only shown if: 1586 // 1) The device has multiple active subscriptions and an SMS default subscription 1587 // hasn't been set, and 1588 // 2) SmsManager is being called from the foreground app. 1589 // Android does not allow background activity starts, so we need to block this. 1590 // if Q+, do not perform requested operation if these two operations are not set. If 1591 // <P, perform these operations on phone 0 (for compatibility purposes, since we 1592 // used to not wait for the result of this activity). 1593 isSmsSimPickActivityNeeded = iSms.isSmsSimPickActivityNeeded(subId); 1594 } 1595 } catch (RemoteException ex) { 1596 Log.e(TAG, "resolveSubscriptionForOperation", ex); 1597 } 1598 if (!isSmsSimPickActivityNeeded) { 1599 sendResolverResult(resolverResult, subId, false /*pickActivityShown*/); 1600 return; 1601 } 1602 // We need to ask the user pick an appropriate subid for the operation. 1603 Log.d(TAG, "resolveSubscriptionForOperation isSmsSimPickActivityNeeded is true for calling" 1604 + " package. "); 1605 try { 1606 // Create the SMS pick activity and call back once the activity is complete. Can't do 1607 // it here because we do not have access to the activity context that is performing this 1608 // operation. 1609 // Requires that the calling process has the SEND_SMS permission. 1610 getITelephony().enqueueSmsPickResult(null, null, 1611 new IIntegerConsumer.Stub() { 1612 @Override 1613 public void accept(int subId) { 1614 // Runs on binder thread attached to this app's process. 1615 sendResolverResult(resolverResult, subId, true /*pickActivityShown*/); 1616 } 1617 }); 1618 } catch (RemoteException ex) { 1619 Log.e(TAG, "Unable to launch activity", ex); 1620 // pickActivityShown is true here because we want to call sendResolverResult and always 1621 // have this operation fail. This is because we received a RemoteException here, which 1622 // means that telephony is not available and the next operation to Telephony will fail 1623 // as well anyways, so we might as well shortcut fail here first. 1624 sendResolverResult(resolverResult, subId, true /*pickActivityShown*/); 1625 } 1626 } 1627 1628 /** 1629 * To check the SDK version for SmsManager.sendResolverResult method. 1630 */ 1631 @ChangeId 1632 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P) 1633 private static final long GET_TARGET_SDK_VERSION_CODE_CHANGE = 145147528L; 1634 sendResolverResult(SubscriptionResolverResult resolverResult, int subId, boolean pickActivityShown)1635 private void sendResolverResult(SubscriptionResolverResult resolverResult, int subId, 1636 boolean pickActivityShown) { 1637 if (SubscriptionManager.isValidSubscriptionId(subId)) { 1638 resolverResult.onSuccess(subId); 1639 return; 1640 } 1641 1642 if (!Compatibility.isChangeEnabled(GET_TARGET_SDK_VERSION_CODE_CHANGE) 1643 && !pickActivityShown) { 1644 // Do not fail, return a success with an INVALID subid for apps targeting P or below 1645 // that tried to perform an operation and the SMS disambiguation dialog was never shown, 1646 // as these applications may not have been written to handle the failure case properly. 1647 // This will resolve to performing the operation on phone 0 in telephony. 1648 resolverResult.onSuccess(subId); 1649 } else { 1650 // Fail if the app targets Q or above or it targets P and below and the disambiguation 1651 // dialog was shown and the user clicked out of it. 1652 resolverResult.onFailure(); 1653 } 1654 } 1655 getITelephony()1656 private static ITelephony getITelephony() { 1657 ITelephony binder = ITelephony.Stub.asInterface( 1658 TelephonyFrameworkInitializer 1659 .getTelephonyServiceManager() 1660 .getTelephonyServiceRegisterer() 1661 .get()); 1662 if (binder == null) { 1663 throw new RuntimeException("Could not find Telephony Service."); 1664 } 1665 return binder; 1666 } 1667 notifySmsError(PendingIntent pendingIntent, int error)1668 private static void notifySmsError(PendingIntent pendingIntent, int error) { 1669 if (pendingIntent != null) { 1670 try { 1671 pendingIntent.send(error); 1672 } catch (PendingIntent.CanceledException e) { 1673 // Don't worry about it, we do not need to notify the caller if this is the case. 1674 } 1675 } 1676 } 1677 notifySmsError(List<PendingIntent> pendingIntents, int error)1678 private static void notifySmsError(List<PendingIntent> pendingIntents, int error) { 1679 if (pendingIntents != null) { 1680 for (PendingIntent pendingIntent : pendingIntents) { 1681 notifySmsError(pendingIntent, error); 1682 } 1683 } 1684 } 1685 1686 /** 1687 * Returns the ISms service, or throws an UnsupportedOperationException if 1688 * the service does not exist. 1689 */ getISmsServiceOrThrow()1690 private static ISms getISmsServiceOrThrow() { 1691 ISms iSms = TelephonyManager.getSmsService(); 1692 if (iSms == null) { 1693 throw new UnsupportedOperationException("Sms is not supported"); 1694 } 1695 return iSms; 1696 } 1697 getISmsService()1698 private static ISms getISmsService() { 1699 return TelephonyManager.getSmsService(); 1700 } 1701 1702 /** 1703 * Copies a raw SMS PDU to the ICC. 1704 * ICC (Integrated Circuit Card) is the card of the device. 1705 * For example, this can be the SIM or USIM for GSM. 1706 * 1707 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 1708 * applications or the Telephony framework and will never trigger an SMS disambiguation 1709 * dialog. If this method is called on a device that has multiple active subscriptions, this 1710 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 1711 * default subscription is defined, the subscription ID associated with this message will be 1712 * INVALID, which will result in the operation being completed on the subscription associated 1713 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 1714 * operation is performed on the correct subscription. 1715 * </p> 1716 * 1717 * @param smsc the SMSC for this messag or null for the default SMSC. 1718 * @param pdu the raw PDU to store. 1719 * @param status message status. One of these status: 1720 * <code>STATUS_ON_ICC_READ</code> 1721 * <code>STATUS_ON_ICC_UNREAD</code> 1722 * <code>STATUS_ON_ICC_SENT</code> 1723 * <code>STATUS_ON_ICC_UNSENT</code> 1724 * @return true for success. Otherwise false. 1725 * 1726 * @throws IllegalArgumentException if pdu is null. 1727 * @hide 1728 */ 1729 @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC) copyMessageToIcc( @ullable byte[] smsc, @NonNull byte[] pdu, @StatusOnIcc int status)1730 public boolean copyMessageToIcc( 1731 @Nullable byte[] smsc, @NonNull byte[] pdu, @StatusOnIcc int status) { 1732 boolean success = false; 1733 1734 if (pdu == null) { 1735 throw new IllegalArgumentException("pdu is null"); 1736 } 1737 try { 1738 ISms iSms = getISmsService(); 1739 if (iSms != null) { 1740 success = iSms.copyMessageToIccEfForSubscriber(getSubscriptionId(), 1741 null, 1742 status, pdu, smsc); 1743 } 1744 } catch (RemoteException ex) { 1745 // ignore it 1746 } 1747 1748 return success; 1749 } 1750 1751 /** 1752 * Deletes the specified message from the ICC. 1753 * ICC (Integrated Circuit Card) is the card of the device. 1754 * For example, this can be the SIM or USIM for GSM. 1755 * 1756 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 1757 * applications or the Telephony framework and will never trigger an SMS disambiguation 1758 * dialog. If this method is called on a device that has multiple active subscriptions, this 1759 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 1760 * default subscription is defined, the subscription ID associated with this message will be 1761 * INVALID, which will result in the operation being completed on the subscription associated 1762 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 1763 * operation is performed on the correct subscription. 1764 * </p> 1765 * 1766 * @param messageIndex the message index of the message in the ICC (1-based index). 1767 * @return true for success, false if the operation fails. Failure can be due to IPC failure, 1768 * RIL/modem error which results in SMS failed to be deleted on SIM 1769 * 1770 * {@hide} 1771 */ 1772 @UnsupportedAppUsage 1773 @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC) deleteMessageFromIcc(int messageIndex)1774 public boolean deleteMessageFromIcc(int messageIndex) { 1775 boolean success = false; 1776 1777 try { 1778 ISms iSms = getISmsService(); 1779 if (iSms != null) { 1780 success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(), 1781 null, 1782 messageIndex, STATUS_ON_ICC_FREE, null /* pdu */); 1783 } 1784 } catch (RemoteException ex) { 1785 // ignore it 1786 } 1787 1788 return success; 1789 } 1790 1791 /** 1792 * Update the specified message on the ICC. 1793 * ICC (Integrated Circuit Card) is the card of the device. 1794 * For example, this can be the SIM or USIM for GSM. 1795 * 1796 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 1797 * applications or the Telephony framework and will never trigger an SMS disambiguation 1798 * dialog. If this method is called on a device that has multiple active subscriptions, this 1799 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 1800 * default subscription is defined, the subscription ID associated with this message will be 1801 * INVALID, which will result in the operation being completed on the subscription associated 1802 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 1803 * operation is performed on the correct subscription. 1804 * </p> 1805 * 1806 * @param messageIndex record index of message to update 1807 * @param newStatus new message status (STATUS_ON_ICC_READ, 1808 * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT, 1809 * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE) 1810 * @param pdu the raw PDU to store 1811 * @return true for success 1812 * 1813 * {@hide} 1814 */ 1815 @UnsupportedAppUsage 1816 @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC) updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu)1817 public boolean updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu) { 1818 boolean success = false; 1819 1820 try { 1821 ISms iSms = getISmsService(); 1822 if (iSms != null) { 1823 success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(), 1824 null, 1825 messageIndex, newStatus, pdu); 1826 } 1827 } catch (RemoteException ex) { 1828 // ignore it 1829 } 1830 1831 return success; 1832 } 1833 1834 /** 1835 * Retrieves all messages currently stored on the ICC. 1836 * ICC (Integrated Circuit Card) is the card of the device. 1837 * For example, this can be the SIM or USIM for GSM. 1838 * 1839 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 1840 * applications or the Telephony framework and will never trigger an SMS disambiguation 1841 * dialog. If this method is called on a device that has multiple active subscriptions, this 1842 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 1843 * default subscription is defined, the subscription ID associated with this message will be 1844 * INVALID, which will result in the operation being completed on the subscription associated 1845 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 1846 * operation is performed on the correct subscription. 1847 * </p> 1848 * 1849 * @return <code>List</code> of <code>SmsMessage</code> objects for valid records only. 1850 * 1851 * {@hide} 1852 */ 1853 @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC) getMessagesFromIcc()1854 public @NonNull List<SmsMessage> getMessagesFromIcc() { 1855 return getAllMessagesFromIcc(); 1856 } 1857 1858 /** 1859 * @return <code>ArrayList</code> of <code>SmsMessage</code> objects 1860 * 1861 * This is similar to {@link #getMessagesFromIcc} except that it will return ArrayList. 1862 * Suggested to use {@link #getMessagesFromIcc} instead. 1863 * 1864 * {@hide} 1865 */ 1866 @UnsupportedAppUsage getAllMessagesFromIcc()1867 public ArrayList<SmsMessage> getAllMessagesFromIcc() { 1868 List<SmsRawData> records = null; 1869 1870 try { 1871 ISms iSms = getISmsService(); 1872 if (iSms != null) { 1873 records = iSms.getAllMessagesFromIccEfForSubscriber( 1874 getSubscriptionId(), 1875 null); 1876 } 1877 } catch (RemoteException ex) { 1878 // ignore it 1879 } 1880 1881 return createMessageListFromRawRecords(records); 1882 } 1883 1884 /** 1885 * Enable reception of cell broadcast (SMS-CB) messages with the given 1886 * message identifier range and RAN type. The RAN type specifies if this message ID 1887 * belongs to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable 1888 * the same message identifier, they must both disable it for the device to stop 1889 * receiving those messages. All received messages will be broadcast in an 1890 * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED". 1891 * Note: This call is blocking, callers may want to avoid calling it from 1892 * the main thread of an application. 1893 * 1894 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 1895 * applications or the Telephony framework and will never trigger an SMS disambiguation 1896 * dialog. If this method is called on a device that has multiple active subscriptions, this 1897 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 1898 * default subscription is defined, the subscription ID associated with this message will be 1899 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}, which will result in the operation 1900 * being completed on the subscription associated with logical slot 0. Use 1901 * {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation is performed on the 1902 * correct subscription. 1903 * </p> 1904 * 1905 * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p> 1906 * 1907 * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) 1908 * or C.R1001-G (3GPP2) 1909 * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) 1910 * or C.R1001-G (3GPP2) 1911 * @param ranType the message format as defined in {@link SmsCbMessage} 1912 * @return true if successful, false if the modem reports a failure (e.g. the given range or 1913 * RAN type is invalid). 1914 * @see #disableCellBroadcastRange(int, int, int) 1915 * 1916 * @throws IllegalArgumentException if endMessageId < startMessageId 1917 * {@hide} 1918 */ 1919 @SystemApi enableCellBroadcastRange(int startMessageId, int endMessageId, @android.telephony.SmsCbMessage.MessageFormat int ranType)1920 public boolean enableCellBroadcastRange(int startMessageId, int endMessageId, 1921 @android.telephony.SmsCbMessage.MessageFormat int ranType) { 1922 boolean success = false; 1923 if (endMessageId < startMessageId) { 1924 throw new IllegalArgumentException("endMessageId < startMessageId"); 1925 } 1926 try { 1927 ISms iSms = getISmsService(); 1928 if (iSms != null) { 1929 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use 1930 // the default phone internally. 1931 int subId = getSubscriptionId(); 1932 success = iSms.enableCellBroadcastRangeForSubscriber(subId, 1933 startMessageId, endMessageId, ranType); 1934 Rlog.d(TAG, "enableCellBroadcastRange: " + (success ? "succeeded" : "failed") 1935 + " at calling enableCellBroadcastRangeForSubscriber. subId = " + subId); 1936 } 1937 } catch (RemoteException ex) { 1938 Rlog.d(TAG, "enableCellBroadcastRange: " + ex.getStackTrace()); 1939 // ignore it 1940 } 1941 1942 return success; 1943 } 1944 1945 /** 1946 * Disable reception of cell broadcast (SMS-CB) messages with the given 1947 * message identifier range and RAN type. The RAN type specify this message 1948 * ID range belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different 1949 * clients enable the same message identifier, they must both disable it for 1950 * the device to stop receiving those messages. 1951 * Note: This call is blocking, callers may want to avoid calling it from 1952 * the main thread of an application. 1953 * 1954 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 1955 * applications or the Telephony framework and will never trigger an SMS disambiguation 1956 * dialog. If this method is called on a device that has multiple active subscriptions, this 1957 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 1958 * default subscription is defined, the subscription ID associated with this message will be 1959 * INVALID, which will result in the operation being completed on the subscription associated 1960 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 1961 * operation is performed on the correct subscription. 1962 * </p> 1963 * 1964 * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p> 1965 * 1966 * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) 1967 * or C.R1001-G (3GPP2) 1968 * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) 1969 * or C.R1001-G (3GPP2) 1970 * @param ranType the message format as defined in {@link SmsCbMessage} 1971 * @return true if successful, false if the modem reports a failure (e.g. the given range or 1972 * RAN type is invalid). 1973 * 1974 * @see #enableCellBroadcastRange(int, int, int) 1975 * 1976 * @throws IllegalArgumentException if endMessageId < startMessageId 1977 * {@hide} 1978 */ 1979 @SystemApi disableCellBroadcastRange(int startMessageId, int endMessageId, @android.telephony.SmsCbMessage.MessageFormat int ranType)1980 public boolean disableCellBroadcastRange(int startMessageId, int endMessageId, 1981 @android.telephony.SmsCbMessage.MessageFormat int ranType) { 1982 boolean success = false; 1983 1984 if (endMessageId < startMessageId) { 1985 throw new IllegalArgumentException("endMessageId < startMessageId"); 1986 } 1987 try { 1988 ISms iSms = getISmsService(); 1989 if (iSms != null) { 1990 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use 1991 // the default phone internally. 1992 int subId = getSubscriptionId(); 1993 success = iSms.disableCellBroadcastRangeForSubscriber(subId, 1994 startMessageId, endMessageId, ranType); 1995 Rlog.d(TAG, "disableCellBroadcastRange: " + (success ? "succeeded" : "failed") 1996 + " at calling disableCellBroadcastRangeForSubscriber. subId = " + subId); 1997 } 1998 } catch (RemoteException ex) { 1999 Rlog.d(TAG, "disableCellBroadcastRange: " + ex.getStackTrace()); 2000 // ignore it 2001 } 2002 2003 return success; 2004 } 2005 2006 /** 2007 * Creates a list of <code>SmsMessage</code>s from a list of SmsRawData records. 2008 * 2009 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 2010 * applications or the Telephony framework and will never trigger an SMS disambiguation 2011 * dialog. If this method is called on a device that has multiple active subscriptions, this 2012 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 2013 * default subscription is defined, the subscription ID associated with this message will be 2014 * INVALID, which will result in the operation being completed on the subscription associated 2015 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 2016 * operation is performed on the correct subscription. 2017 * </p> 2018 * 2019 * @param records SMS EF records. 2020 * @return <code>ArrayList</code> of <code>SmsMessage</code> objects. 2021 */ createMessageListFromRawRecords(List<SmsRawData> records)2022 private ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) { 2023 ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>(); 2024 if (records != null) { 2025 int count = records.size(); 2026 for (int i = 0; i < count; i++) { 2027 SmsRawData data = records.get(i); 2028 // List contains all records, including "free" records (null) 2029 if (data != null) { 2030 SmsMessage sms = SmsMessage.createFromEfRecord(i + 1, data.getBytes(), 2031 getSubscriptionId()); 2032 if (sms != null) { 2033 messages.add(sms); 2034 } 2035 } 2036 } 2037 } 2038 return messages; 2039 } 2040 2041 /** 2042 * SMS over IMS is supported if IMS is registered and SMS is supported 2043 * on IMS. 2044 * 2045 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 2046 * applications or the Telephony framework and will never trigger an SMS disambiguation 2047 * dialog. If this method is called on a device that has multiple active subscriptions, this 2048 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 2049 * default subscription is defined, the subscription ID associated with this message will be 2050 * INVALID, which will result in the operation being completed on the subscription associated 2051 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 2052 * operation is performed on the correct subscription. 2053 * </p> 2054 * 2055 * @return true if SMS over IMS is supported, false otherwise 2056 * 2057 * @see #getImsSmsFormat() 2058 * 2059 * @hide 2060 */ isImsSmsSupported()2061 public boolean isImsSmsSupported() { 2062 boolean boSupported = false; 2063 try { 2064 ISms iSms = getISmsService(); 2065 if (iSms != null) { 2066 boSupported = iSms.isImsSmsSupportedForSubscriber(getSubscriptionId()); 2067 } 2068 } catch (RemoteException ex) { 2069 // ignore it 2070 } 2071 return boSupported; 2072 } 2073 2074 /** 2075 * Gets SMS format supported on IMS. SMS over IMS format is either 3GPP or 3GPP2. 2076 * 2077 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 2078 * applications or the Telephony framework and will never trigger an SMS disambiguation 2079 * dialog. If this method is called on a device that has multiple active subscriptions, this 2080 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 2081 * default subscription is defined, the subscription ID associated with this message will be 2082 * INVALID, which will result in the operation being completed on the subscription associated 2083 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 2084 * operation is performed on the correct subscription. 2085 * </p> 2086 * 2087 * @return SmsMessage.FORMAT_3GPP, 2088 * SmsMessage.FORMAT_3GPP2 2089 * or SmsMessage.FORMAT_UNKNOWN 2090 * 2091 * @see #isImsSmsSupported() 2092 * 2093 * @hide 2094 */ getImsSmsFormat()2095 public String getImsSmsFormat() { 2096 String format = com.android.internal.telephony.SmsConstants.FORMAT_UNKNOWN; 2097 try { 2098 ISms iSms = getISmsService(); 2099 if (iSms != null) { 2100 format = iSms.getImsSmsFormatForSubscriber(getSubscriptionId()); 2101 } 2102 } catch (RemoteException ex) { 2103 // ignore it 2104 } 2105 return format; 2106 } 2107 2108 /** 2109 * Get default sms subscription id. 2110 * 2111 * <p class="note"><strong>Note:</strong>This returns a value different from 2112 * {@link SubscriptionManager#getDefaultSmsSubscriptionId} if the user has not chosen a default. 2113 * In this case it returns the active subscription id if there's only one active subscription 2114 * available. 2115 * 2116 * @return the user-defined default SMS subscription id, or the active subscription id if 2117 * there's only one active subscription available, otherwise 2118 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. 2119 */ getDefaultSmsSubscriptionId()2120 public static int getDefaultSmsSubscriptionId() { 2121 try { 2122 return getISmsService().getPreferredSmsSubscription(); 2123 } catch (RemoteException e) { 2124 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2125 } catch (NullPointerException e) { 2126 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2127 } 2128 } 2129 2130 /** 2131 * Get SMS prompt property, enabled or not 2132 * 2133 * @return true if enabled, false otherwise 2134 * @hide 2135 */ 2136 @UnsupportedAppUsage isSMSPromptEnabled()2137 public boolean isSMSPromptEnabled() { 2138 ISms iSms = null; 2139 try { 2140 iSms = TelephonyManager.getSmsService(); 2141 return iSms.isSMSPromptEnabled(); 2142 } catch (RemoteException ex) { 2143 return false; 2144 } catch (NullPointerException ex) { 2145 return false; 2146 } 2147 } 2148 2149 /** 2150 * Gets the total capacity of SMS storage on the SIM card. 2151 * 2152 * <p> 2153 * This is the number of 176 byte EF-SMS records which can be stored on the SIM card. 2154 * See 3GPP TS 31.102 - 4.2.25 - EF-SMS for more information. 2155 * </p> 2156 * 2157 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation 2158 * dialog. If this method is called on a device that has multiple active subscriptions, this 2159 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 2160 * default subscription is defined, the subscription ID associated with this method will be 2161 * INVALID, which will result in the operation being completed on the subscription associated 2162 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation 2163 * is performed on the correct subscription. 2164 * </p> 2165 * 2166 * @return the total number of SMS records which can be stored on the SIM card. 2167 */ 2168 @RequiresPermission(anyOf = {android.Manifest.permission.READ_PHONE_STATE, 2169 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE}) 2170 @IntRange(from = 0) getSmsCapacityOnIcc()2171 public int getSmsCapacityOnIcc() { 2172 int ret = 0; 2173 try { 2174 ISms iccISms = getISmsService(); 2175 if (iccISms != null) { 2176 ret = iccISms.getSmsCapacityOnIccForSubscriber(getSubscriptionId()); 2177 } 2178 } catch (RemoteException ex) { 2179 Log.e(TAG, "getSmsCapacityOnIcc() RemoteException", ex); 2180 } 2181 return ret; 2182 } 2183 2184 /** @hide */ 2185 @IntDef(prefix = { "STATUS_ON_ICC_" }, value = { 2186 STATUS_ON_ICC_FREE, 2187 STATUS_ON_ICC_READ, 2188 STATUS_ON_ICC_UNREAD, 2189 STATUS_ON_ICC_SENT, 2190 STATUS_ON_ICC_UNSENT 2191 }) 2192 @Retention(RetentionPolicy.SOURCE) 2193 public @interface StatusOnIcc {} 2194 2195 // see SmsMessage.getStatusOnIcc 2196 2197 /** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */ 2198 public static final int STATUS_ON_ICC_FREE = 0; 2199 2200 /** Received and read (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */ 2201 public static final int STATUS_ON_ICC_READ = 1; 2202 2203 /** Received and unread (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */ 2204 public static final int STATUS_ON_ICC_UNREAD = 3; 2205 2206 /** Stored and sent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */ 2207 public static final int STATUS_ON_ICC_SENT = 5; 2208 2209 /** Stored and unsent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */ 2210 public static final int STATUS_ON_ICC_UNSENT = 7; 2211 2212 // SMS send failure result codes 2213 2214 /** @hide */ 2215 @IntDef(prefix = { "RESULT" }, value = { 2216 RESULT_ERROR_NONE, 2217 RESULT_ERROR_GENERIC_FAILURE, 2218 RESULT_ERROR_RADIO_OFF, 2219 RESULT_ERROR_NULL_PDU, 2220 RESULT_ERROR_NO_SERVICE, 2221 RESULT_ERROR_LIMIT_EXCEEDED, 2222 RESULT_ERROR_FDN_CHECK_FAILURE, 2223 RESULT_ERROR_SHORT_CODE_NOT_ALLOWED, 2224 RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED, 2225 RESULT_RADIO_NOT_AVAILABLE, 2226 RESULT_NETWORK_REJECT, 2227 RESULT_INVALID_ARGUMENTS, 2228 RESULT_INVALID_STATE, 2229 RESULT_NO_MEMORY, 2230 RESULT_INVALID_SMS_FORMAT, 2231 RESULT_SYSTEM_ERROR, 2232 RESULT_MODEM_ERROR, 2233 RESULT_NETWORK_ERROR, 2234 RESULT_INVALID_SMSC_ADDRESS, 2235 RESULT_OPERATION_NOT_ALLOWED, 2236 RESULT_INTERNAL_ERROR, 2237 RESULT_NO_RESOURCES, 2238 RESULT_CANCELLED, 2239 RESULT_REQUEST_NOT_SUPPORTED, 2240 RESULT_NO_BLUETOOTH_SERVICE, 2241 RESULT_INVALID_BLUETOOTH_ADDRESS, 2242 RESULT_BLUETOOTH_DISCONNECTED, 2243 RESULT_UNEXPECTED_EVENT_STOP_SENDING, 2244 RESULT_SMS_BLOCKED_DURING_EMERGENCY, 2245 RESULT_SMS_SEND_RETRY_FAILED, 2246 RESULT_REMOTE_EXCEPTION, 2247 RESULT_NO_DEFAULT_SMS_APP, 2248 RESULT_RIL_RADIO_NOT_AVAILABLE, 2249 RESULT_RIL_SMS_SEND_FAIL_RETRY, 2250 RESULT_RIL_NETWORK_REJECT, 2251 RESULT_RIL_INVALID_STATE, 2252 RESULT_RIL_INVALID_ARGUMENTS, 2253 RESULT_RIL_NO_MEMORY, 2254 RESULT_RIL_REQUEST_RATE_LIMITED, 2255 RESULT_RIL_INVALID_SMS_FORMAT, 2256 RESULT_RIL_SYSTEM_ERR, 2257 RESULT_RIL_ENCODING_ERR, 2258 RESULT_RIL_INVALID_SMSC_ADDRESS, 2259 RESULT_RIL_MODEM_ERR, 2260 RESULT_RIL_NETWORK_ERR, 2261 RESULT_RIL_INTERNAL_ERR, 2262 RESULT_RIL_REQUEST_NOT_SUPPORTED, 2263 RESULT_RIL_INVALID_MODEM_STATE, 2264 RESULT_RIL_NETWORK_NOT_READY, 2265 RESULT_RIL_OPERATION_NOT_ALLOWED, 2266 RESULT_RIL_NO_RESOURCES, 2267 RESULT_RIL_CANCELLED, 2268 RESULT_RIL_SIM_ABSENT, 2269 RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED, 2270 RESULT_RIL_ACCESS_BARRED, 2271 RESULT_RIL_BLOCKED_DUE_TO_CALL 2272 }) 2273 @Retention(RetentionPolicy.SOURCE) 2274 public @interface Result {} 2275 2276 /** 2277 * No error. 2278 */ 2279 public static final int RESULT_ERROR_NONE = 0; 2280 2281 /** Generic failure cause */ 2282 public static final int RESULT_ERROR_GENERIC_FAILURE = 1; 2283 2284 /** Failed because radio was explicitly turned off */ 2285 public static final int RESULT_ERROR_RADIO_OFF = 2; 2286 2287 /** Failed because no pdu provided */ 2288 public static final int RESULT_ERROR_NULL_PDU = 3; 2289 2290 /** Failed because service is currently unavailable */ 2291 public static final int RESULT_ERROR_NO_SERVICE = 4; 2292 2293 /** Failed because we reached the sending queue limit. */ 2294 public static final int RESULT_ERROR_LIMIT_EXCEEDED = 5; 2295 2296 /** 2297 * Failed because FDN is enabled. 2298 */ 2299 public static final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; 2300 2301 /** Failed because user denied the sending of this short code. */ 2302 public static final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7; 2303 2304 /** Failed because the user has denied this app ever send premium short codes. */ 2305 public static final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8; 2306 2307 /** 2308 * Failed because the radio was not available 2309 */ 2310 public static final int RESULT_RADIO_NOT_AVAILABLE = 9; 2311 2312 /** 2313 * Failed because of network rejection 2314 */ 2315 public static final int RESULT_NETWORK_REJECT = 10; 2316 2317 /** 2318 * Failed because of invalid arguments 2319 */ 2320 public static final int RESULT_INVALID_ARGUMENTS = 11; 2321 2322 /** 2323 * Failed because of an invalid state 2324 */ 2325 public static final int RESULT_INVALID_STATE = 12; 2326 2327 /** 2328 * Failed because there is no memory 2329 */ 2330 public static final int RESULT_NO_MEMORY = 13; 2331 2332 /** 2333 * Failed because the sms format is not valid 2334 */ 2335 public static final int RESULT_INVALID_SMS_FORMAT = 14; 2336 2337 /** 2338 * Failed because of a system error 2339 */ 2340 public static final int RESULT_SYSTEM_ERROR = 15; 2341 2342 /** 2343 * Failed because of a modem error 2344 */ 2345 public static final int RESULT_MODEM_ERROR = 16; 2346 2347 /** 2348 * Failed because of a network error 2349 */ 2350 public static final int RESULT_NETWORK_ERROR = 17; 2351 2352 /** 2353 * Failed because of an encoding error 2354 */ 2355 public static final int RESULT_ENCODING_ERROR = 18; 2356 2357 /** 2358 * Failed because of an invalid smsc address 2359 */ 2360 public static final int RESULT_INVALID_SMSC_ADDRESS = 19; 2361 2362 /** 2363 * Failed because the operation is not allowed 2364 */ 2365 public static final int RESULT_OPERATION_NOT_ALLOWED = 20; 2366 2367 /** 2368 * Failed because of an internal error 2369 */ 2370 public static final int RESULT_INTERNAL_ERROR = 21; 2371 2372 /** 2373 * Failed because there are no resources 2374 */ 2375 public static final int RESULT_NO_RESOURCES = 22; 2376 2377 /** 2378 * Failed because the operation was cancelled 2379 */ 2380 public static final int RESULT_CANCELLED = 23; 2381 2382 /** 2383 * Failed because the request is not supported 2384 */ 2385 public static final int RESULT_REQUEST_NOT_SUPPORTED = 24; 2386 2387 /** 2388 * Failed sending via bluetooth because the bluetooth service is not available 2389 */ 2390 public static final int RESULT_NO_BLUETOOTH_SERVICE = 25; 2391 2392 /** 2393 * Failed sending via bluetooth because the bluetooth device address is invalid 2394 */ 2395 public static final int RESULT_INVALID_BLUETOOTH_ADDRESS = 26; 2396 2397 /** 2398 * Failed sending via bluetooth because bluetooth disconnected 2399 */ 2400 public static final int RESULT_BLUETOOTH_DISCONNECTED = 27; 2401 2402 /** 2403 * Failed sending because the user denied or canceled the dialog displayed for a premium 2404 * shortcode sms or rate-limited sms. 2405 */ 2406 public static final int RESULT_UNEXPECTED_EVENT_STOP_SENDING = 28; 2407 2408 /** 2409 * Failed sending during an emergency call 2410 */ 2411 public static final int RESULT_SMS_BLOCKED_DURING_EMERGENCY = 29; 2412 2413 /** 2414 * Failed to send an sms retry 2415 */ 2416 public static final int RESULT_SMS_SEND_RETRY_FAILED = 30; 2417 2418 /** 2419 * Set by BroadcastReceiver to indicate a remote exception while handling a message. 2420 */ 2421 public static final int RESULT_REMOTE_EXCEPTION = 31; 2422 2423 /** 2424 * Set by BroadcastReceiver to indicate there's no default sms app. 2425 */ 2426 public static final int RESULT_NO_DEFAULT_SMS_APP = 32; 2427 2428 // Radio Error results 2429 2430 /** 2431 * The radio did not start or is resetting. 2432 */ 2433 public static final int RESULT_RIL_RADIO_NOT_AVAILABLE = 100; 2434 2435 /** 2436 * The radio failed to send the sms and needs to retry. 2437 */ 2438 public static final int RESULT_RIL_SMS_SEND_FAIL_RETRY = 101; 2439 2440 /** 2441 * The sms request was rejected by the network. 2442 */ 2443 public static final int RESULT_RIL_NETWORK_REJECT = 102; 2444 2445 /** 2446 * The radio returned an unexpected request for the current state. 2447 */ 2448 public static final int RESULT_RIL_INVALID_STATE = 103; 2449 2450 /** 2451 * The radio received invalid arguments in the request. 2452 */ 2453 public static final int RESULT_RIL_INVALID_ARGUMENTS = 104; 2454 2455 /** 2456 * The radio didn't have sufficient memory to process the request. 2457 */ 2458 public static final int RESULT_RIL_NO_MEMORY = 105; 2459 2460 /** 2461 * The radio denied the operation due to overly-frequent requests. 2462 */ 2463 public static final int RESULT_RIL_REQUEST_RATE_LIMITED = 106; 2464 2465 /** 2466 * The radio returned an error indicating invalid sms format. 2467 */ 2468 public static final int RESULT_RIL_INVALID_SMS_FORMAT = 107; 2469 2470 /** 2471 * The radio encountered a platform or system error. 2472 */ 2473 public static final int RESULT_RIL_SYSTEM_ERR = 108; 2474 2475 /** 2476 * The SMS message was not encoded properly. 2477 */ 2478 public static final int RESULT_RIL_ENCODING_ERR = 109; 2479 2480 /** 2481 * The specified SMSC address was invalid. 2482 */ 2483 public static final int RESULT_RIL_INVALID_SMSC_ADDRESS = 110; 2484 2485 /** 2486 * The vendor RIL received an unexpected or incorrect response. 2487 */ 2488 public static final int RESULT_RIL_MODEM_ERR = 111; 2489 2490 /** 2491 * The radio received an error from the network. 2492 */ 2493 public static final int RESULT_RIL_NETWORK_ERR = 112; 2494 2495 /** 2496 * The modem encountered an unexpected error scenario while handling the request. 2497 */ 2498 public static final int RESULT_RIL_INTERNAL_ERR = 113; 2499 2500 /** 2501 * The request was not supported by the radio. 2502 */ 2503 public static final int RESULT_RIL_REQUEST_NOT_SUPPORTED = 114; 2504 2505 /** 2506 * The radio cannot process the request in the current modem state. 2507 */ 2508 public static final int RESULT_RIL_INVALID_MODEM_STATE = 115; 2509 2510 /** 2511 * The network is not ready to perform the request. 2512 */ 2513 public static final int RESULT_RIL_NETWORK_NOT_READY = 116; 2514 2515 /** 2516 * The radio reports the request is not allowed. 2517 */ 2518 public static final int RESULT_RIL_OPERATION_NOT_ALLOWED = 117; 2519 2520 /** 2521 * There are insufficient resources to process the request. 2522 */ 2523 public static final int RESULT_RIL_NO_RESOURCES = 118; 2524 2525 /** 2526 * The request has been cancelled. 2527 */ 2528 public static final int RESULT_RIL_CANCELLED = 119; 2529 2530 /** 2531 * The radio failed to set the location where the CDMA subscription 2532 * can be retrieved because the SIM or RUIM is absent. 2533 */ 2534 public static final int RESULT_RIL_SIM_ABSENT = 120; 2535 2536 /** 2537 * 1X voice and SMS are not allowed simulteneously. 2538 */ 2539 public static final int RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 121; 2540 2541 /** 2542 * Access is barred. 2543 */ 2544 public static final int RESULT_RIL_ACCESS_BARRED = 122; 2545 2546 /** 2547 * SMS is blocked due to call control, e.g., resource unavailable in the SMR entity. 2548 */ 2549 public static final int RESULT_RIL_BLOCKED_DUE_TO_CALL = 123; 2550 2551 /** 2552 * A RIL error occurred during the SMS send. 2553 */ 2554 public static final int RESULT_RIL_GENERIC_ERROR = 124; 2555 2556 // SMS receiving results sent as a "result" extra in {@link Intents.SMS_REJECTED_ACTION} 2557 2558 /** 2559 * SMS receive dispatch failure. 2560 */ 2561 public static final int RESULT_RECEIVE_DISPATCH_FAILURE = 500; 2562 2563 /** 2564 * SMS receive injected null PDU. 2565 */ 2566 public static final int RESULT_RECEIVE_INJECTED_NULL_PDU = 501; 2567 2568 /** 2569 * SMS receive encountered runtime exception. 2570 */ 2571 public static final int RESULT_RECEIVE_RUNTIME_EXCEPTION = 502; 2572 2573 /** 2574 * SMS received null message from the radio interface layer. 2575 */ 2576 public static final int RESULT_RECEIVE_NULL_MESSAGE_FROM_RIL = 503; 2577 2578 /** 2579 * SMS short code received while the phone is in encrypted state. 2580 */ 2581 public static final int RESULT_RECEIVE_WHILE_ENCRYPTED = 504; 2582 2583 /** 2584 * SMS receive encountered an SQL exception. 2585 */ 2586 public static final int RESULT_RECEIVE_SQL_EXCEPTION = 505; 2587 2588 /** 2589 * SMS receive an exception parsing a uri. 2590 */ 2591 public static final int RESULT_RECEIVE_URI_EXCEPTION = 506; 2592 2593 2594 2595 /** 2596 * Send an MMS message 2597 * 2598 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 2599 * manager on a multi-SIM device, this operation may fail sending the MMS message because no 2600 * suitable default subscription could be found. In this case, if {@code sentIntent} is 2601 * non-null, then the {@link PendingIntent} will be sent with an error code 2602 * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the 2603 * conditions where this operation may fail. 2604 * </p> 2605 * 2606 * @param context application context 2607 * @param contentUri the content Uri from which the message pdu will be read 2608 * @param locationUrl the optional location url where message should be sent to 2609 * @param configOverrides the carrier-specific messaging configuration values to override for 2610 * sending the message. 2611 * @param sentIntent if not NULL this <code>PendingIntent</code> is 2612 * broadcast when the message is successfully sent, or failed 2613 * The result code will be <code>Activity.RESULT_OK</code> for success 2614 * or one of these errors:<br> 2615 * <code>MMS_ERROR_UNSPECIFIED</code><br> 2616 * <code>MMS_ERROR_INVALID_APN</code><br> 2617 * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br> 2618 * <code>MMS_ERROR_HTTP_FAILURE</code><br> 2619 * <code>MMS_ERROR_IO_ERROR</code><br> 2620 * <code>MMS_ERROR_RETRY</code><br> 2621 * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br> 2622 * <code>MMS_ERROR_NO_DATA_NETWORK</code><br> 2623 * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br> 2624 * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br> 2625 * <code>MMS_ERROR_DATA_DISABLED</code><br> 2626 * @throws IllegalArgumentException if contentUri is empty 2627 */ sendMultimediaMessage(Context context, Uri contentUri, String locationUrl, Bundle configOverrides, PendingIntent sentIntent)2628 public void sendMultimediaMessage(Context context, Uri contentUri, String locationUrl, 2629 Bundle configOverrides, PendingIntent sentIntent) { 2630 sendMultimediaMessage(context, contentUri, locationUrl, configOverrides, sentIntent, 2631 0L /* messageId */); 2632 } 2633 2634 /** 2635 * Send an MMS message 2636 * 2637 * Same as {@link #sendMultimediaMessage(Context context, Uri contentUri, String locationUrl, 2638 * Bundle configOverrides, PendingIntent sentIntent)}, but adds an optional messageId. 2639 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 2640 * manager on a multi-SIM device, this operation may fail sending the MMS message because no 2641 * suitable default subscription could be found. In this case, if {@code sentIntent} is 2642 * non-null, then the {@link PendingIntent} will be sent with an error code 2643 * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the 2644 * conditions where this operation may fail. 2645 * </p> 2646 * 2647 * @param context application context 2648 * @param contentUri the content Uri from which the message pdu will be read 2649 * @param locationUrl the optional location url where message should be sent to 2650 * @param configOverrides the carrier-specific messaging configuration values to override for 2651 * sending the message. 2652 * @param sentIntent if not NULL this <code>PendingIntent</code> is 2653 * broadcast when the message is successfully sent, or failed 2654 * The result code will be <code>Activity.RESULT_OK</code> for success 2655 * or one of these errors:<br> 2656 * <code>MMS_ERROR_UNSPECIFIED</code><br> 2657 * <code>MMS_ERROR_INVALID_APN</code><br> 2658 * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br> 2659 * <code>MMS_ERROR_HTTP_FAILURE</code><br> 2660 * <code>MMS_ERROR_IO_ERROR</code><br> 2661 * <code>MMS_ERROR_RETRY</code><br> 2662 * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br> 2663 * <code>MMS_ERROR_NO_DATA_NETWORK</code><br> 2664 * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br> 2665 * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br> 2666 * <code>MMS_ERROR_DATA_DISABLED</code><br> 2667 * @param messageId an id that uniquely identifies the message requested to be sent. 2668 * Used for logging and diagnostics purposes. The id may be 0. 2669 * @throws IllegalArgumentException if contentUri is empty 2670 */ sendMultimediaMessage(@onNull Context context, @NonNull Uri contentUri, @Nullable String locationUrl, @SuppressWarnings("NullableCollection") @Nullable Bundle configOverrides, @Nullable PendingIntent sentIntent, long messageId)2671 public void sendMultimediaMessage(@NonNull Context context, @NonNull Uri contentUri, 2672 @Nullable String locationUrl, 2673 @SuppressWarnings("NullableCollection") @Nullable Bundle configOverrides, 2674 @Nullable PendingIntent sentIntent, long messageId) { 2675 if (contentUri == null) { 2676 throw new IllegalArgumentException("Uri contentUri null"); 2677 } 2678 MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE); 2679 if (m != null) { 2680 resolveSubscriptionForOperation(new SubscriptionResolverResult() { 2681 @Override 2682 public void onSuccess(int subId) { 2683 m.sendMultimediaMessage(subId, contentUri, locationUrl, configOverrides, 2684 sentIntent, messageId); 2685 } 2686 2687 @Override 2688 public void onFailure() { 2689 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP); 2690 } 2691 }); 2692 } 2693 } 2694 2695 /** 2696 * Download an MMS message from carrier by a given location URL 2697 * 2698 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 2699 * manager on a multi-SIM device, this operation may fail downloading the MMS message because no 2700 * suitable default subscription could be found. In this case, if {@code downloadedIntent} is 2701 * non-null, then the {@link PendingIntent} will be sent with an error code 2702 * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the 2703 * conditions where this operation may fail. 2704 * </p> 2705 * 2706 * @param context application context 2707 * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained 2708 * from the MMS WAP push notification 2709 * @param contentUri the content uri to which the downloaded pdu will be written 2710 * @param configOverrides the carrier-specific messaging configuration values to override for 2711 * downloading the message. 2712 * @param downloadedIntent if not NULL this <code>PendingIntent</code> is 2713 * broadcast when the message is downloaded, or the download is failed 2714 * The result code will be <code>Activity.RESULT_OK</code> for success 2715 * or one of these errors:<br> 2716 * <code>MMS_ERROR_UNSPECIFIED</code><br> 2717 * <code>MMS_ERROR_INVALID_APN</code><br> 2718 * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br> 2719 * <code>MMS_ERROR_HTTP_FAILURE</code><br> 2720 * <code>MMS_ERROR_IO_ERROR</code><br> 2721 * <code>MMS_ERROR_RETRY</code><br> 2722 * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br> 2723 * <code>MMS_ERROR_NO_DATA_NETWORK</code><br> 2724 * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br> 2725 * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br> 2726 * <code>MMS_ERROR_DATA_DISABLED</code><br> 2727 * @throws IllegalArgumentException if locationUrl or contentUri is empty 2728 */ downloadMultimediaMessage(Context context, String locationUrl, Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent)2729 public void downloadMultimediaMessage(Context context, String locationUrl, Uri contentUri, 2730 Bundle configOverrides, PendingIntent downloadedIntent) { 2731 downloadMultimediaMessage(context, locationUrl, contentUri, configOverrides, 2732 downloadedIntent, 0L /* messageId */); 2733 } 2734 2735 /** 2736 * Download an MMS message from carrier by a given location URL 2737 * 2738 * Same as {@link #downloadMultimediaMessage(Context context, String locationUrl, 2739 * Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent)}, 2740 * but adds an optional messageId. 2741 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this 2742 * manager on a multi-SIM device, this operation may fail downloading the MMS message because no 2743 * suitable default subscription could be found. In this case, if {@code downloadedIntent} is 2744 * non-null, then the {@link PendingIntent} will be sent with an error code 2745 * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the 2746 * conditions where this operation may fail. 2747 * </p> 2748 * 2749 * @param context application context 2750 * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained 2751 * from the MMS WAP push notification 2752 * @param contentUri the content uri to which the downloaded pdu will be written 2753 * @param configOverrides the carrier-specific messaging configuration values to override for 2754 * downloading the message. 2755 * @param downloadedIntent if not NULL this <code>PendingIntent</code> is 2756 * broadcast when the message is downloaded, or the download is failed 2757 * The result code will be <code>Activity.RESULT_OK</code> for success 2758 * or one of these errors:<br> 2759 * <code>MMS_ERROR_UNSPECIFIED</code><br> 2760 * <code>MMS_ERROR_INVALID_APN</code><br> 2761 * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br> 2762 * <code>MMS_ERROR_HTTP_FAILURE</code><br> 2763 * <code>MMS_ERROR_IO_ERROR</code><br> 2764 * <code>MMS_ERROR_RETRY</code><br> 2765 * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br> 2766 * <code>MMS_ERROR_NO_DATA_NETWORK</code><br> 2767 * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br> 2768 * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br> 2769 * <code>MMS_ERROR_DATA_DISABLED</code><br> 2770 * @param messageId an id that uniquely identifies the message requested to be downloaded. 2771 * Used for logging and diagnostics purposes. The id may be 0. 2772 * @throws IllegalArgumentException if locationUrl or contentUri is empty 2773 */ downloadMultimediaMessage(@onNull Context context, @NonNull String locationUrl, @NonNull Uri contentUri, @SuppressWarnings("NullableCollection") @Nullable Bundle configOverrides, @Nullable PendingIntent downloadedIntent, long messageId)2774 public void downloadMultimediaMessage(@NonNull Context context, @NonNull String locationUrl, 2775 @NonNull Uri contentUri, 2776 @SuppressWarnings("NullableCollection") @Nullable Bundle configOverrides, 2777 @Nullable PendingIntent downloadedIntent, long messageId) { 2778 if (TextUtils.isEmpty(locationUrl)) { 2779 throw new IllegalArgumentException("Empty MMS location URL"); 2780 } 2781 if (contentUri == null) { 2782 throw new IllegalArgumentException("Uri contentUri null"); 2783 } 2784 MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE); 2785 if (m != null) { 2786 resolveSubscriptionForOperation(new SubscriptionResolverResult() { 2787 @Override 2788 public void onSuccess(int subId) { 2789 m.downloadMultimediaMessage(subId, locationUrl, contentUri, configOverrides, 2790 downloadedIntent, messageId); 2791 } 2792 2793 @Override 2794 public void onFailure() { 2795 notifySmsError(downloadedIntent, RESULT_NO_DEFAULT_SMS_APP); 2796 } 2797 }); 2798 } 2799 } 2800 2801 // MMS send/download failure result codes 2802 2803 /** 2804 * Unspecific MMS error occurred during send/download. 2805 */ 2806 public static final int MMS_ERROR_UNSPECIFIED = 1; 2807 2808 /** 2809 * ApnException occurred during MMS network setup. 2810 */ 2811 public static final int MMS_ERROR_INVALID_APN = 2; 2812 2813 /** 2814 * An error occurred during the MMS connection setup. 2815 */ 2816 public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3; 2817 2818 /** 2819 * An error occurred during the HTTP client setup. 2820 */ 2821 public static final int MMS_ERROR_HTTP_FAILURE = 4; 2822 2823 /** 2824 * An I/O error occurred reading the PDU. 2825 */ 2826 public static final int MMS_ERROR_IO_ERROR = 5; 2827 2828 /** 2829 * An error occurred while retrying sending/downloading the MMS. 2830 */ 2831 public static final int MMS_ERROR_RETRY = 6; 2832 2833 /** 2834 * The carrier-dependent configuration values could not be loaded. 2835 */ 2836 public static final int MMS_ERROR_CONFIGURATION_ERROR = 7; 2837 2838 /** 2839 * There is no data network. 2840 */ 2841 public static final int MMS_ERROR_NO_DATA_NETWORK = 8; 2842 2843 /** 2844 * The subscription id for the send/download is invalid. 2845 */ 2846 public static final int MMS_ERROR_INVALID_SUBSCRIPTION_ID = 9; 2847 2848 /** 2849 * The subscription id for the send/download is inactive. 2850 */ 2851 public static final int MMS_ERROR_INACTIVE_SUBSCRIPTION = 10; 2852 2853 /** 2854 * Data is disabled for the MMS APN. 2855 */ 2856 public static final int MMS_ERROR_DATA_DISABLED = 11; 2857 2858 /** Intent extra name for MMS sending result data in byte array type */ 2859 public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA"; 2860 /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */ 2861 public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS"; 2862 2863 /** 2864 * Get carrier-dependent MMS configuration values. 2865 * 2866 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 2867 * applications or the Telephony framework and will never trigger an SMS disambiguation dialog. 2868 * If this method is called on a device that has multiple active subscriptions, this {@link 2869 * SmsManager} instance has been created with {@link #getDefault()}, and no user-defined default 2870 * subscription is defined, the subscription ID associated with this message will be INVALID, 2871 * which will result in the operation being completed on the subscription associated with 2872 * logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation is 2873 * performed on the correct subscription. 2874 * </p> 2875 * 2876 * @return the bundle key/values pairs that contains MMS configuration values 2877 * or an empty Bundle if they cannot be found. 2878 */ getCarrierConfigValues()2879 @NonNull public Bundle getCarrierConfigValues() { 2880 try { 2881 ISms iSms = getISmsService(); 2882 if (iSms != null) { 2883 return iSms.getCarrierConfigValuesForSubscriber(getSubscriptionId()); 2884 } 2885 } catch (RemoteException ex) { 2886 // ignore it 2887 } 2888 return new Bundle(); 2889 } 2890 2891 /** 2892 * Create a single use app specific incoming SMS request for the calling package. 2893 * 2894 * This method returns a token that if included in a subsequent incoming SMS message will cause 2895 * {@code intent} to be sent with the SMS data. 2896 * 2897 * The token is only good for one use, after an SMS has been received containing the token all 2898 * subsequent SMS messages with the token will be routed as normal. 2899 * 2900 * An app can only have one request at a time, if the app already has a request pending it will 2901 * be replaced with a new request. 2902 * 2903 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation 2904 * dialog. If this method is called on a device that has multiple active subscriptions, this 2905 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 2906 * default subscription is defined, the subscription ID associated with this message will be 2907 * INVALID, which will result in the operation being completed on the subscription associated 2908 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 2909 * operation is performed on the correct subscription. 2910 * </p> 2911 * 2912 * @return Token to include in an SMS message. The token will be 11 characters long. 2913 * @see android.provider.Telephony.Sms.Intents#getMessagesFromIntent 2914 */ createAppSpecificSmsToken(PendingIntent intent)2915 public String createAppSpecificSmsToken(PendingIntent intent) { 2916 try { 2917 ISms iccSms = getISmsServiceOrThrow(); 2918 return iccSms.createAppSpecificSmsToken(getSubscriptionId(), 2919 null, intent); 2920 2921 } catch (RemoteException ex) { 2922 ex.rethrowFromSystemServer(); 2923 return null; 2924 } 2925 } 2926 2927 /** 2928 * callback for providing asynchronous sms messages for financial app. 2929 */ 2930 public abstract static class FinancialSmsCallback { 2931 /** 2932 * Callback to send sms messages back to financial app asynchronously. 2933 * 2934 * @param msgs SMS messages. 2935 */ onFinancialSmsMessages(CursorWindow msgs)2936 public abstract void onFinancialSmsMessages(CursorWindow msgs); 2937 }; 2938 2939 /** 2940 * Get SMS messages for the calling financial app. 2941 * The result will be delivered asynchronously in the passing in callback interface. 2942 * 2943 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation 2944 * dialog. If this method is called on a device that has multiple active subscriptions, this 2945 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 2946 * default subscription is defined, the subscription ID associated with this message will be 2947 * INVALID, which will result in the operation being completed on the subscription associated 2948 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 2949 * operation is performed on the correct subscription. 2950 * </p> 2951 * 2952 * @param params the parameters to filter SMS messages returned. 2953 * @param executor the executor on which callback will be invoked. 2954 * @param callback a callback to receive CursorWindow with SMS messages. 2955 * 2956 */ 2957 @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS) getSmsMessagesForFinancialApp( Bundle params, @NonNull @CallbackExecutor Executor executor, @NonNull FinancialSmsCallback callback)2958 public void getSmsMessagesForFinancialApp( 2959 Bundle params, 2960 @NonNull @CallbackExecutor Executor executor, 2961 @NonNull FinancialSmsCallback callback) { 2962 // This API is not functional and thus removed to avoid future confusion. 2963 } 2964 2965 /** 2966 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). 2967 * The prefixes is a list of prefix {@code String} separated by this delimiter. 2968 * @hide 2969 */ 2970 public static final String REGEX_PREFIX_DELIMITER = ","; 2971 /** 2972 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). 2973 * The success status to be added into the intent to be sent to the calling package. 2974 * @hide 2975 */ 2976 public static final int RESULT_STATUS_SUCCESS = 0; 2977 /** 2978 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). 2979 * The timeout status to be added into the intent to be sent to the calling package. 2980 * @hide 2981 */ 2982 public static final int RESULT_STATUS_TIMEOUT = 1; 2983 /** 2984 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). 2985 * Intent extra key of the retrieved SMS message as a {@code String}. 2986 * @hide 2987 */ 2988 public static final String EXTRA_SMS_MESSAGE = "android.telephony.extra.SMS_MESSAGE"; 2989 /** 2990 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). 2991 * Intent extra key of SMS retriever status, which indicates whether the request for the 2992 * coming SMS message is SUCCESS or TIMEOUT 2993 * @hide 2994 */ 2995 public static final String EXTRA_STATUS = "android.telephony.extra.STATUS"; 2996 /** 2997 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). 2998 * [Optional] Intent extra key of the retrieved Sim card subscription Id if any. {@code int} 2999 * @hide 3000 */ 3001 public static final String EXTRA_SIM_SUBSCRIPTION_ID = 3002 "android.telephony.extra.SIM_SUBSCRIPTION_ID"; 3003 3004 /** 3005 * Create a single use app specific incoming SMS request for the calling package. 3006 * 3007 * This method returns a token that if included in a subsequent incoming SMS message, and the 3008 * SMS message has a prefix from the given prefixes list, the provided {@code intent} will be 3009 * sent with the SMS data to the calling package. 3010 * 3011 * The token is only good for one use within a reasonable amount of time. After an SMS has been 3012 * received containing the token all subsequent SMS messages with the token will be routed as 3013 * normal. 3014 * 3015 * An app can only have one request at a time, if the app already has a request pending it will 3016 * be replaced with a new request. 3017 * 3018 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation 3019 * dialog. If this method is called on a device that has multiple active subscriptions, this 3020 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 3021 * default subscription is defined, the subscription ID associated with this message will be 3022 * INVALID, which will result in the operation being completed on the subscription associated 3023 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 3024 * operation is performed on the correct subscription. 3025 * </p> 3026 * 3027 * @param prefixes this is a list of prefixes string separated by REGEX_PREFIX_DELIMITER. The 3028 * matching SMS message should have at least one of the prefixes in the beginning of the 3029 * message. 3030 * @param intent this intent is sent when the matching SMS message is received. 3031 * @return Token to include in an SMS message. 3032 */ 3033 @Nullable createAppSpecificSmsTokenWithPackageInfo( @ullable String prefixes, @NonNull PendingIntent intent)3034 public String createAppSpecificSmsTokenWithPackageInfo( 3035 @Nullable String prefixes, @NonNull PendingIntent intent) { 3036 try { 3037 ISms iccSms = getISmsServiceOrThrow(); 3038 return iccSms.createAppSpecificSmsTokenWithPackageInfo(getSubscriptionId(), 3039 null, prefixes, intent); 3040 3041 } catch (RemoteException ex) { 3042 ex.rethrowFromSystemServer(); 3043 return null; 3044 } 3045 } 3046 3047 /** @hide */ 3048 @Retention(RetentionPolicy.SOURCE) 3049 @IntDef(prefix = {"SMS_CATEGORY_"}, 3050 value = { 3051 SmsManager.SMS_CATEGORY_NOT_SHORT_CODE, 3052 SmsManager.SMS_CATEGORY_FREE_SHORT_CODE, 3053 SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE, 3054 SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE, 3055 SmsManager.SMS_CATEGORY_PREMIUM_SHORT_CODE}) 3056 public @interface SmsShortCodeCategory {} 3057 3058 /** 3059 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for regular 3060 * phone numbers. 3061 * @hide 3062 */ 3063 @TestApi 3064 public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; 3065 /** 3066 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for free 3067 * (no cost) short codes. 3068 * @hide 3069 */ 3070 @TestApi 3071 public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; 3072 /** 3073 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for 3074 * standard rate (non-premium) 3075 * short codes. 3076 * @hide 3077 */ 3078 @TestApi 3079 public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2; 3080 /** 3081 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for possible 3082 * premium short codes. 3083 * @hide 3084 */ 3085 @TestApi 3086 public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; 3087 /** 3088 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for 3089 * premium short codes. 3090 * @hide 3091 */ 3092 @TestApi 3093 public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4; 3094 3095 /** 3096 * Check if the destination address is a possible premium short code. 3097 * NOTE: the caller is expected to strip non-digits from the destination number with 3098 * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method. 3099 * 3100 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier 3101 * applications or the Telephony framework and will never trigger an SMS disambiguation 3102 * dialog. If this method is called on a device that has multiple active subscriptions, this 3103 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 3104 * default subscription is defined, the subscription ID associated with this message will be 3105 * INVALID, which will result in the operation being completed on the subscription associated 3106 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the 3107 * operation is performed on the correct subscription. 3108 * </p> 3109 * 3110 * @param destAddress the destination address to test for possible short code 3111 * @param countryIso the ISO country code 3112 * 3113 * @return 3114 * {@link SmsManager#SMS_CATEGORY_NOT_SHORT_CODE}, 3115 * {@link SmsManager#SMS_CATEGORY_FREE_SHORT_CODE}, 3116 * {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE}, 3117 * {@link SmsManager#SMS_CATEGORY_PREMIUM_SHORT_CODE}, or 3118 * {@link SmsManager#SMS_CATEGORY_STANDARD_SHORT_CODE} 3119 * 3120 * @hide 3121 */ 3122 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) 3123 @TestApi checkSmsShortCodeDestination( String destAddress, String countryIso)3124 public @SmsShortCodeCategory int checkSmsShortCodeDestination( 3125 String destAddress, String countryIso) { 3126 try { 3127 ISms iccISms = getISmsServiceOrThrow(); 3128 if (iccISms != null) { 3129 return iccISms.checkSmsShortCodeDestination(getSubscriptionId(), 3130 null, null, destAddress, countryIso); 3131 } 3132 } catch (RemoteException e) { 3133 Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e); 3134 } 3135 return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE; 3136 } 3137 3138 /** 3139 * Gets the SMSC address from (U)SIM. 3140 * 3141 * <p class="note"><strong>Note:</strong> Using this method requires that your app is the 3142 * default SMS application, or READ_PRIVILEGED_PHONE_STATE permission, or has the carrier 3143 * privileges.</p> 3144 * 3145 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation 3146 * dialog. If this method is called on a device that has multiple active subscriptions, this 3147 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 3148 * default subscription is defined, the subscription ID associated with this method will be 3149 * INVALID, which will result in the operation being completed on the subscription associated 3150 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation 3151 * is performed on the correct subscription. 3152 * </p> 3153 * 3154 * @return the SMSC address string, null if failed. 3155 */ 3156 @SuppressAutoDoc // for carrier privileges and default SMS application. 3157 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) 3158 @Nullable getSmscAddress()3159 public String getSmscAddress() { 3160 String smsc = null; 3161 3162 try { 3163 ISms iSms = getISmsService(); 3164 if (iSms != null) { 3165 smsc = iSms.getSmscAddressFromIccEfForSubscriber( 3166 getSubscriptionId(), null); 3167 } 3168 } catch (RemoteException ex) { 3169 throw new RuntimeException(ex); 3170 } 3171 return smsc; 3172 } 3173 3174 /** 3175 * Sets the SMSC address on (U)SIM. 3176 * 3177 * <p class="note"><strong>Note:</strong> Using this method requires that your app is the 3178 * default SMS application, or has {@link android.Manifest.permission#MODIFY_PHONE_STATE} 3179 * permission, or has the carrier privileges.</p> 3180 * 3181 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation 3182 * dialog. If this method is called on a device that has multiple active subscriptions, this 3183 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined 3184 * default subscription is defined, the subscription ID associated with this method will be 3185 * INVALID, which will result in the operation being completed on the subscription associated 3186 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation 3187 * is performed on the correct subscription. 3188 * </p> 3189 * 3190 * @param smsc the SMSC address string. 3191 * @return true for success, false otherwise. Failure can be due modem returning an error. 3192 */ 3193 @SuppressAutoDoc // for carrier privileges and default SMS application. 3194 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setSmscAddress(@onNull String smsc)3195 public boolean setSmscAddress(@NonNull String smsc) { 3196 try { 3197 ISms iSms = getISmsService(); 3198 if (iSms != null) { 3199 return iSms.setSmscAddressOnIccEfForSubscriber( 3200 smsc, getSubscriptionId(), null); 3201 } 3202 } catch (RemoteException ex) { 3203 throw new RuntimeException(ex); 3204 } 3205 return false; 3206 } 3207 3208 /** 3209 * Gets the premium SMS permission for the specified package. If the package has never 3210 * been seen before, the default {@link SmsManager#PREMIUM_SMS_CONSENT_UNKNOWN} 3211 * will be returned. 3212 * @param packageName the name of the package to query permission 3213 * @return one of {@link SmsManager#PREMIUM_SMS_CONSENT_UNKNOWN}, 3214 * {@link SmsManager#PREMIUM_SMS_CONSENT_ASK_USER}, 3215 * {@link SmsManager#PREMIUM_SMS_CONSENT_NEVER_ALLOW}, or 3216 * {@link SmsManager#PREMIUM_SMS_CONSENT_ALWAYS_ALLOW} 3217 * @hide 3218 */ 3219 @SystemApi 3220 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) getPremiumSmsConsent(@onNull String packageName)3221 public @PremiumSmsConsent int getPremiumSmsConsent(@NonNull String packageName) { 3222 int permission = 0; 3223 try { 3224 ISms iSms = getISmsService(); 3225 if (iSms != null) { 3226 permission = iSms.getPremiumSmsPermission(packageName); 3227 } 3228 } catch (RemoteException e) { 3229 Log.e(TAG, "getPremiumSmsPermission() RemoteException", e); 3230 } 3231 return permission; 3232 } 3233 3234 /** 3235 * Sets the premium SMS permission for the specified package and save the value asynchronously 3236 * to persistent storage. 3237 * @param packageName the name of the package to set permission 3238 * @param permission one of {@link SmsManager#PREMIUM_SMS_CONSENT_ASK_USER}, 3239 * {@link SmsManager#PREMIUM_SMS_CONSENT_NEVER_ALLOW}, or 3240 * {@link SmsManager#PREMIUM_SMS_CONSENT_ALWAYS_ALLOW} 3241 * @hide 3242 */ 3243 @SystemApi 3244 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) setPremiumSmsConsent( @onNull String packageName, @PremiumSmsConsent int permission)3245 public void setPremiumSmsConsent( 3246 @NonNull String packageName, @PremiumSmsConsent int permission) { 3247 try { 3248 ISms iSms = getISmsService(); 3249 if (iSms != null) { 3250 iSms.setPremiumSmsPermission(packageName, permission); 3251 } 3252 } catch (RemoteException e) { 3253 Log.e(TAG, "setPremiumSmsPermission() RemoteException", e); 3254 } 3255 } 3256 3257 /** 3258 * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this. 3259 * @hide 3260 */ 3261 @SystemApi 3262 @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) resetAllCellBroadcastRanges()3263 public void resetAllCellBroadcastRanges() { 3264 try { 3265 ISms iSms = getISmsService(); 3266 if (iSms != null) { 3267 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use 3268 // the default phone internally. 3269 iSms.resetAllCellBroadcastRanges(getSubscriptionId()); 3270 } 3271 } catch (RemoteException ex) { 3272 ex.rethrowFromSystemServer(); 3273 } 3274 } 3275 formatCrossStackMessageId(long id)3276 private static String formatCrossStackMessageId(long id) { 3277 return "{x-message-id:" + id + "}"; 3278 } 3279 } 3280