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