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