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