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