Home | History | Annotate | Download | only in provider
      1 /*
      2  * Copyright (C) 2006 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.provider;
     18 
     19 import android.annotation.SdkConstant;
     20 import android.annotation.SdkConstant.SdkConstantType;
     21 import android.content.ComponentName;
     22 import android.content.ContentResolver;
     23 import android.content.ContentValues;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.database.Cursor;
     27 import android.database.sqlite.SqliteWrapper;
     28 import android.net.Uri;
     29 import android.telephony.SmsMessage;
     30 import android.telephony.SubscriptionManager;
     31 import android.text.TextUtils;
     32 import android.telephony.Rlog;
     33 import android.util.Patterns;
     34 
     35 import com.android.internal.telephony.PhoneConstants;
     36 import com.android.internal.telephony.SmsApplication;
     37 
     38 
     39 import java.util.HashSet;
     40 import java.util.Set;
     41 import java.util.regex.Matcher;
     42 import java.util.regex.Pattern;
     43 
     44 /**
     45  * The Telephony provider contains data related to phone operation, specifically SMS and MMS
     46  * messages and access to the APN list, including the MMSC to use.
     47  *
     48  * <p class="note"><strong>Note:</strong> These APIs are not available on all Android-powered
     49  * devices. If your app depends on telephony features such as for managing SMS messages, include
     50  * a <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code &lt;uses-feature>}
     51  * </a> element in your manifest that declares the {@code "android.hardware.telephony"} hardware
     52  * feature. Alternatively, you can check for telephony availability at runtime using either
     53  * {@link android.content.pm.PackageManager#hasSystemFeature
     54  * hasSystemFeature(PackageManager.FEATURE_TELEPHONY)} or {@link
     55  * android.telephony.TelephonyManager#getPhoneType}.</p>
     56  *
     57  * <h3>Creating an SMS app</h3>
     58  *
     59  * <p>Only the default SMS app (selected by the user in system settings) is able to write to the
     60  * SMS Provider (the tables defined within the {@code Telephony} class) and only the default SMS
     61  * app receives the {@link android.provider.Telephony.Sms.Intents#SMS_DELIVER_ACTION} broadcast
     62  * when the user receives an SMS or the {@link
     63  * android.provider.Telephony.Sms.Intents#WAP_PUSH_DELIVER_ACTION} broadcast when the user
     64  * receives an MMS.</p>
     65  *
     66  * <p>Any app that wants to behave as the user's default SMS app must handle the following intents:
     67  * <ul>
     68  * <li>In a broadcast receiver, include an intent filter for {@link Sms.Intents#SMS_DELIVER_ACTION}
     69  * (<code>"android.provider.Telephony.SMS_DELIVER"</code>). The broadcast receiver must also
     70  * require the {@link android.Manifest.permission#BROADCAST_SMS} permission.
     71  * <p>This allows your app to directly receive incoming SMS messages.</p></li>
     72  * <li>In a broadcast receiver, include an intent filter for {@link
     73  * Sms.Intents#WAP_PUSH_DELIVER_ACTION}} ({@code "android.provider.Telephony.WAP_PUSH_DELIVER"})
     74  * with the MIME type <code>"application/vnd.wap.mms-message"</code>.
     75  * The broadcast receiver must also require the {@link
     76  * android.Manifest.permission#BROADCAST_WAP_PUSH} permission.
     77  * <p>This allows your app to directly receive incoming MMS messages.</p></li>
     78  * <li>In your activity that delivers new messages, include an intent filter for
     79  * {@link android.content.Intent#ACTION_SENDTO} (<code>"android.intent.action.SENDTO"
     80  * </code>) with schemas, <code>sms:</code>, <code>smsto:</code>, <code>mms:</code>, and
     81  * <code>mmsto:</code>.
     82  * <p>This allows your app to receive intents from other apps that want to deliver a
     83  * message.</p></li>
     84  * <li>In a service, include an intent filter for {@link
     85  * android.telephony.TelephonyManager#ACTION_RESPOND_VIA_MESSAGE}
     86  * (<code>"android.intent.action.RESPOND_VIA_MESSAGE"</code>) with schemas,
     87  * <code>sms:</code>, <code>smsto:</code>, <code>mms:</code>, and <code>mmsto:</code>.
     88  * This service must also require the {@link
     89  * android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE} permission.
     90  * <p>This allows users to respond to incoming phone calls with an immediate text message
     91  * using your app.</p></li>
     92  * </ul>
     93  *
     94  * <p>Other apps that are not selected as the default SMS app can only <em>read</em> the SMS
     95  * Provider, but may also be notified when a new SMS arrives by listening for the {@link
     96  * Sms.Intents#SMS_RECEIVED_ACTION}
     97  * broadcast, which is a non-abortable broadcast that may be delivered to multiple apps. This
     98  * broadcast is intended for apps that&mdash;while not selected as the default SMS app&mdash;need to
     99  * read special incoming messages such as to perform phone number verification.</p>
    100  *
    101  * <p>For more information about building SMS apps, read the blog post, <a
    102  * href="http://android-developers.blogspot.com/2013/10/getting-your-sms-apps-ready-for-kitkat.html"
    103  * >Getting Your SMS Apps Ready for KitKat</a>.</p>
    104  *
    105  */
    106 public final class Telephony {
    107     private static final String TAG = "Telephony";
    108 
    109     /**
    110      * Not instantiable.
    111      * @hide
    112      */
    113     private Telephony() {
    114     }
    115 
    116     /**
    117      * Base columns for tables that contain text-based SMSs.
    118      */
    119     public interface TextBasedSmsColumns {
    120 
    121         /** Message type: all messages. */
    122         public static final int MESSAGE_TYPE_ALL    = 0;
    123 
    124         /** Message type: inbox. */
    125         public static final int MESSAGE_TYPE_INBOX  = 1;
    126 
    127         /** Message type: sent messages. */
    128         public static final int MESSAGE_TYPE_SENT   = 2;
    129 
    130         /** Message type: drafts. */
    131         public static final int MESSAGE_TYPE_DRAFT  = 3;
    132 
    133         /** Message type: outbox. */
    134         public static final int MESSAGE_TYPE_OUTBOX = 4;
    135 
    136         /** Message type: failed outgoing message. */
    137         public static final int MESSAGE_TYPE_FAILED = 5;
    138 
    139         /** Message type: queued to send later. */
    140         public static final int MESSAGE_TYPE_QUEUED = 6;
    141 
    142         /**
    143          * The type of message.
    144          * <P>Type: INTEGER</P>
    145          */
    146         public static final String TYPE = "type";
    147 
    148         /**
    149          * The thread ID of the message.
    150          * <P>Type: INTEGER</P>
    151          */
    152         public static final String THREAD_ID = "thread_id";
    153 
    154         /**
    155          * The address of the other party.
    156          * <P>Type: TEXT</P>
    157          */
    158         public static final String ADDRESS = "address";
    159 
    160         /**
    161          * The date the message was received.
    162          * <P>Type: INTEGER (long)</P>
    163          */
    164         public static final String DATE = "date";
    165 
    166         /**
    167          * The date the message was sent.
    168          * <P>Type: INTEGER (long)</P>
    169          */
    170         public static final String DATE_SENT = "date_sent";
    171 
    172         /**
    173          * Has the message been read?
    174          * <P>Type: INTEGER (boolean)</P>
    175          */
    176         public static final String READ = "read";
    177 
    178         /**
    179          * Has the message been seen by the user? The "seen" flag determines
    180          * whether we need to show a notification.
    181          * <P>Type: INTEGER (boolean)</P>
    182          */
    183         public static final String SEEN = "seen";
    184 
    185         /**
    186          * {@code TP-Status} value for the message, or -1 if no status has been received.
    187          * <P>Type: INTEGER</P>
    188          */
    189         public static final String STATUS = "status";
    190 
    191         /** TP-Status: no status received. */
    192         public static final int STATUS_NONE = -1;
    193         /** TP-Status: complete. */
    194         public static final int STATUS_COMPLETE = 0;
    195         /** TP-Status: pending. */
    196         public static final int STATUS_PENDING = 32;
    197         /** TP-Status: failed. */
    198         public static final int STATUS_FAILED = 64;
    199 
    200         /**
    201          * The subject of the message, if present.
    202          * <P>Type: TEXT</P>
    203          */
    204         public static final String SUBJECT = "subject";
    205 
    206         /**
    207          * The body of the message.
    208          * <P>Type: TEXT</P>
    209          */
    210         public static final String BODY = "body";
    211 
    212         /**
    213          * The ID of the sender of the conversation, if present.
    214          * <P>Type: INTEGER (reference to item in {@code content://contacts/people})</P>
    215          */
    216         public static final String PERSON = "person";
    217 
    218         /**
    219          * The protocol identifier code.
    220          * <P>Type: INTEGER</P>
    221          */
    222         public static final String PROTOCOL = "protocol";
    223 
    224         /**
    225          * Is the {@code TP-Reply-Path} flag set?
    226          * <P>Type: BOOLEAN</P>
    227          */
    228         public static final String REPLY_PATH_PRESENT = "reply_path_present";
    229 
    230         /**
    231          * The service center (SC) through which to send the message, if present.
    232          * <P>Type: TEXT</P>
    233          */
    234         public static final String SERVICE_CENTER = "service_center";
    235 
    236         /**
    237          * Is the message locked?
    238          * <P>Type: INTEGER (boolean)</P>
    239          */
    240         public static final String LOCKED = "locked";
    241 
    242         /**
    243          * The sub_id to which the message belongs to
    244          * <p>Type: INTEGER (long) </p>
    245          * @hide
    246          */
    247         public static final String SUB_ID = "sub_id";
    248 
    249         /**
    250          * The MTU size of the mobile interface to which the APN connected
    251          * @hide
    252          */
    253         public static final String MTU = "mtu";
    254 
    255         /**
    256          * Error code associated with sending or receiving this message
    257          * <P>Type: INTEGER</P>
    258          */
    259         public static final String ERROR_CODE = "error_code";
    260 
    261         /**
    262          * The identity of the sender of a sent message. It is
    263          * usually the package name of the app which sends the message.
    264          * <p>Type: TEXT</p>
    265          */
    266         public static final String CREATOR = "creator";
    267     }
    268 
    269     /**
    270      * Contains all text-based SMS messages.
    271      */
    272     public static final class Sms implements BaseColumns, TextBasedSmsColumns {
    273 
    274         /**
    275          * Not instantiable.
    276          * @hide
    277          */
    278         private Sms() {
    279         }
    280 
    281         /**
    282          * Used to determine the currently configured default SMS package.
    283          * @param context context of the requesting application
    284          * @return package name for the default SMS package or null
    285          */
    286         public static String getDefaultSmsPackage(Context context) {
    287             ComponentName component = SmsApplication.getDefaultSmsApplication(context, false);
    288             if (component != null) {
    289                 return component.getPackageName();
    290             }
    291             return null;
    292         }
    293 
    294         /**
    295          * Return cursor for table query.
    296          * @hide
    297          */
    298         public static Cursor query(ContentResolver cr, String[] projection) {
    299             return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
    300         }
    301 
    302         /**
    303          * Return cursor for table query.
    304          * @hide
    305          */
    306         public static Cursor query(ContentResolver cr, String[] projection,
    307                 String where, String orderBy) {
    308             return cr.query(CONTENT_URI, projection, where,
    309                     null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
    310         }
    311 
    312         /**
    313          * The {@code content://} style URL for this table.
    314          */
    315         public static final Uri CONTENT_URI = Uri.parse("content://sms");
    316 
    317         /**
    318          * The default sort order for this table.
    319          */
    320         public static final String DEFAULT_SORT_ORDER = "date DESC";
    321 
    322         /**
    323          * Add an SMS to the given URI.
    324          *
    325          * @param resolver the content resolver to use
    326          * @param uri the URI to add the message to
    327          * @param address the address of the sender
    328          * @param body the body of the message
    329          * @param subject the pseudo-subject of the message
    330          * @param date the timestamp for the message
    331          * @param read true if the message has been read, false if not
    332          * @param deliveryReport true if a delivery report was requested, false if not
    333          * @return the URI for the new message
    334          * @hide
    335          */
    336         public static Uri addMessageToUri(ContentResolver resolver,
    337                 Uri uri, String address, String body, String subject,
    338                 Long date, boolean read, boolean deliveryReport) {
    339             return addMessageToUri(SubscriptionManager.getDefaultSmsSubId(),
    340                     resolver, uri, address, body, subject, date, read, deliveryReport, -1L);
    341         }
    342 
    343         /**
    344          * Add an SMS to the given URI.
    345          *
    346          * @param resolver the content resolver to use
    347          * @param uri the URI to add the message to
    348          * @param address the address of the sender
    349          * @param body the body of the message
    350          * @param subject the psuedo-subject of the message
    351          * @param date the timestamp for the message
    352          * @param read true if the message has been read, false if not
    353          * @param deliveryReport true if a delivery report was requested, false if not
    354          * @param subId the sub_id which the message belongs to
    355          * @return the URI for the new message
    356          * @hide
    357          */
    358         public static Uri addMessageToUri(long subId, ContentResolver resolver,
    359                 Uri uri, String address, String body, String subject,
    360                 Long date, boolean read, boolean deliveryReport) {
    361             return addMessageToUri(subId, resolver, uri, address, body, subject,
    362                     date, read, deliveryReport, -1L);
    363         }
    364 
    365         /**
    366          * Add an SMS to the given URI with the specified thread ID.
    367          *
    368          * @param resolver the content resolver to use
    369          * @param uri the URI to add the message to
    370          * @param address the address of the sender
    371          * @param body the body of the message
    372          * @param subject the pseudo-subject of the message
    373          * @param date the timestamp for the message
    374          * @param read true if the message has been read, false if not
    375          * @param deliveryReport true if a delivery report was requested, false if not
    376          * @param threadId the thread_id of the message
    377          * @return the URI for the new message
    378          * @hide
    379          */
    380         public static Uri addMessageToUri(ContentResolver resolver,
    381                 Uri uri, String address, String body, String subject,
    382                 Long date, boolean read, boolean deliveryReport, long threadId) {
    383             return addMessageToUri(SubscriptionManager.getDefaultSmsSubId(),
    384                     resolver, uri, address, body, subject,
    385                     date, read, deliveryReport, threadId);
    386         }
    387 
    388         /**
    389          * Add an SMS to the given URI with thread_id specified.
    390          *
    391          * @param resolver the content resolver to use
    392          * @param uri the URI to add the message to
    393          * @param address the address of the sender
    394          * @param body the body of the message
    395          * @param subject the psuedo-subject of the message
    396          * @param date the timestamp for the message
    397          * @param read true if the message has been read, false if not
    398          * @param deliveryReport true if a delivery report was requested, false if not
    399          * @param threadId the thread_id of the message
    400          * @param subId the sub_id which the message belongs to
    401          * @return the URI for the new message
    402          * @hide
    403          */
    404         public static Uri addMessageToUri(long subId, ContentResolver resolver,
    405                 Uri uri, String address, String body, String subject,
    406                 Long date, boolean read, boolean deliveryReport, long threadId) {
    407             ContentValues values = new ContentValues(8);
    408             Rlog.v(TAG,"Telephony addMessageToUri sub id: " + subId);
    409 
    410             values.put(SUB_ID, subId);
    411             values.put(ADDRESS, address);
    412             if (date != null) {
    413                 values.put(DATE, date);
    414             }
    415             values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
    416             values.put(SUBJECT, subject);
    417             values.put(BODY, body);
    418             if (deliveryReport) {
    419                 values.put(STATUS, STATUS_PENDING);
    420             }
    421             if (threadId != -1L) {
    422                 values.put(THREAD_ID, threadId);
    423             }
    424             return resolver.insert(uri, values);
    425         }
    426 
    427         /**
    428          * Move a message to the given folder.
    429          *
    430          * @param context the context to use
    431          * @param uri the message to move
    432          * @param folder the folder to move to
    433          * @return true if the operation succeeded
    434          * @hide
    435          */
    436         public static boolean moveMessageToFolder(Context context,
    437                 Uri uri, int folder, int error) {
    438             if (uri == null) {
    439                 return false;
    440             }
    441 
    442             boolean markAsUnread = false;
    443             boolean markAsRead = false;
    444             switch(folder) {
    445             case MESSAGE_TYPE_INBOX:
    446             case MESSAGE_TYPE_DRAFT:
    447                 break;
    448             case MESSAGE_TYPE_OUTBOX:
    449             case MESSAGE_TYPE_SENT:
    450                 markAsRead = true;
    451                 break;
    452             case MESSAGE_TYPE_FAILED:
    453             case MESSAGE_TYPE_QUEUED:
    454                 markAsUnread = true;
    455                 break;
    456             default:
    457                 return false;
    458             }
    459 
    460             ContentValues values = new ContentValues(3);
    461 
    462             values.put(TYPE, folder);
    463             if (markAsUnread) {
    464                 values.put(READ, 0);
    465             } else if (markAsRead) {
    466                 values.put(READ, 1);
    467             }
    468             values.put(ERROR_CODE, error);
    469 
    470             return 1 == SqliteWrapper.update(context, context.getContentResolver(),
    471                             uri, values, null, null);
    472         }
    473 
    474         /**
    475          * Returns true iff the folder (message type) identifies an
    476          * outgoing message.
    477          * @hide
    478          */
    479         public static boolean isOutgoingFolder(int messageType) {
    480             return  (messageType == MESSAGE_TYPE_FAILED)
    481                     || (messageType == MESSAGE_TYPE_OUTBOX)
    482                     || (messageType == MESSAGE_TYPE_SENT)
    483                     || (messageType == MESSAGE_TYPE_QUEUED);
    484         }
    485 
    486         /**
    487          * Contains all text-based SMS messages in the SMS app inbox.
    488          */
    489         public static final class Inbox implements BaseColumns, TextBasedSmsColumns {
    490 
    491             /**
    492              * Not instantiable.
    493              * @hide
    494              */
    495             private Inbox() {
    496             }
    497 
    498             /**
    499              * The {@code content://} style URL for this table.
    500              */
    501             public static final Uri CONTENT_URI = Uri.parse("content://sms/inbox");
    502 
    503             /**
    504              * The default sort order for this table.
    505              */
    506             public static final String DEFAULT_SORT_ORDER = "date DESC";
    507 
    508             /**
    509              * Add an SMS to the Draft box.
    510              *
    511              * @param resolver the content resolver to use
    512              * @param address the address of the sender
    513              * @param body the body of the message
    514              * @param subject the pseudo-subject of the message
    515              * @param date the timestamp for the message
    516              * @param read true if the message has been read, false if not
    517              * @return the URI for the new message
    518              * @hide
    519              */
    520             public static Uri addMessage(ContentResolver resolver,
    521                     String address, String body, String subject, Long date,
    522                     boolean read) {
    523                 return addMessageToUri(SubscriptionManager.getDefaultSmsSubId(),
    524                         resolver, CONTENT_URI, address, body, subject, date, read, false);
    525             }
    526 
    527             /**
    528              * Add an SMS to the Draft box.
    529              *
    530              * @param resolver the content resolver to use
    531              * @param address the address of the sender
    532              * @param body the body of the message
    533              * @param subject the psuedo-subject of the message
    534              * @param date the timestamp for the message
    535              * @param read true if the message has been read, false if not
    536              * @param subId the sub_id which the message belongs to
    537              * @return the URI for the new message
    538              * @hide
    539              */
    540             public static Uri addMessage(long subId, ContentResolver resolver,
    541                     String address, String body, String subject, Long date, boolean read) {
    542                 return addMessageToUri(subId, resolver, CONTENT_URI, address, body,
    543                         subject, date, read, false);
    544             }
    545         }
    546 
    547         /**
    548          * Contains all sent text-based SMS messages in the SMS app.
    549          */
    550         public static final class Sent implements BaseColumns, TextBasedSmsColumns {
    551 
    552             /**
    553              * Not instantiable.
    554              * @hide
    555              */
    556             private Sent() {
    557             }
    558 
    559             /**
    560              * The {@code content://} style URL for this table.
    561              */
    562             public static final Uri CONTENT_URI = Uri.parse("content://sms/sent");
    563 
    564             /**
    565              * The default sort order for this table.
    566              */
    567             public static final String DEFAULT_SORT_ORDER = "date DESC";
    568 
    569             /**
    570              * Add an SMS to the Draft box.
    571              *
    572              * @param resolver the content resolver to use
    573              * @param address the address of the sender
    574              * @param body the body of the message
    575              * @param subject the pseudo-subject of the message
    576              * @param date the timestamp for the message
    577              * @return the URI for the new message
    578              * @hide
    579              */
    580             public static Uri addMessage(ContentResolver resolver,
    581                     String address, String body, String subject, Long date) {
    582                 return addMessageToUri(SubscriptionManager.getDefaultSmsSubId(),
    583                         resolver, CONTENT_URI, address, body, subject, date, true, false);
    584             }
    585 
    586             /**
    587              * Add an SMS to the Draft box.
    588              *
    589              * @param resolver the content resolver to use
    590              * @param address the address of the sender
    591              * @param body the body of the message
    592              * @param subject the psuedo-subject of the message
    593              * @param date the timestamp for the message
    594              * @param subId the sub_id which the message belongs to
    595              * @return the URI for the new message
    596              * @hide
    597              */
    598             public static Uri addMessage(long subId, ContentResolver resolver,
    599                     String address, String body, String subject, Long date) {
    600                 return addMessageToUri(subId, resolver, CONTENT_URI, address, body,
    601                         subject, date, true, false);
    602             }
    603         }
    604 
    605         /**
    606          * Contains all sent text-based SMS messages in the SMS app.
    607          */
    608         public static final class Draft implements BaseColumns, TextBasedSmsColumns {
    609 
    610             /**
    611              * Not instantiable.
    612              * @hide
    613              */
    614             private Draft() {
    615             }
    616 
    617             /**
    618              * The {@code content://} style URL for this table.
    619              */
    620             public static final Uri CONTENT_URI = Uri.parse("content://sms/draft");
    621 
    622            /**
    623             * @hide
    624             */
    625             public static Uri addMessage(ContentResolver resolver,
    626                     String address, String body, String subject, Long date) {
    627                 return addMessageToUri(SubscriptionManager.getDefaultSmsSubId(),
    628                         resolver, CONTENT_URI, address, body, subject, date, true, false);
    629             }
    630 
    631             /**
    632              * Add an SMS to the Draft box.
    633              *
    634              * @param resolver the content resolver to use
    635              * @param address the address of the sender
    636              * @param body the body of the message
    637              * @param subject the psuedo-subject of the message
    638              * @param date the timestamp for the message
    639              * @param subId the sub_id which the message belongs to
    640              * @return the URI for the new message
    641              * @hide
    642              */
    643             public static Uri addMessage(long subId, ContentResolver resolver,
    644                     String address, String body, String subject, Long date) {
    645                 return addMessageToUri(subId, resolver, CONTENT_URI, address, body,
    646                         subject, date, true, false);
    647             }
    648 
    649             /**
    650              * The default sort order for this table.
    651              */
    652             public static final String DEFAULT_SORT_ORDER = "date DESC";
    653         }
    654 
    655         /**
    656          * Contains all pending outgoing text-based SMS messages.
    657          */
    658         public static final class Outbox implements BaseColumns, TextBasedSmsColumns {
    659 
    660             /**
    661              * Not instantiable.
    662              * @hide
    663              */
    664             private Outbox() {
    665             }
    666 
    667             /**
    668              * The {@code content://} style URL for this table.
    669              */
    670             public static final Uri CONTENT_URI = Uri.parse("content://sms/outbox");
    671 
    672             /**
    673              * The default sort order for this table.
    674              */
    675             public static final String DEFAULT_SORT_ORDER = "date DESC";
    676 
    677             /**
    678              * Add an SMS to the outbox.
    679              *
    680              * @param resolver the content resolver to use
    681              * @param address the address of the sender
    682              * @param body the body of the message
    683              * @param subject the pseudo-subject of the message
    684              * @param date the timestamp for the message
    685              * @param deliveryReport whether a delivery report was requested for the message
    686              * @return the URI for the new message
    687              * @hide
    688              */
    689             public static Uri addMessage(ContentResolver resolver,
    690                     String address, String body, String subject, Long date,
    691                     boolean deliveryReport, long threadId) {
    692                 return addMessageToUri(SubscriptionManager.getDefaultSmsSubId(),
    693                         resolver, CONTENT_URI, address, body, subject, date,
    694                         true, deliveryReport, threadId);
    695             }
    696 
    697             /**
    698              * Add an SMS to the Out box.
    699              *
    700              * @param resolver the content resolver to use
    701              * @param address the address of the sender
    702              * @param body the body of the message
    703              * @param subject the psuedo-subject of the message
    704              * @param date the timestamp for the message
    705              * @param deliveryReport whether a delivery report was requested for the message
    706              * @param subId the sub_id which the message belongs to
    707              * @return the URI for the new message
    708              * @hide
    709              */
    710             public static Uri addMessage(long subId, ContentResolver resolver,
    711                     String address, String body, String subject, Long date,
    712                     boolean deliveryReport, long threadId) {
    713                 return addMessageToUri(subId, resolver, CONTENT_URI, address, body,
    714                         subject, date, true, deliveryReport, threadId);
    715             }
    716         }
    717 
    718         /**
    719          * Contains all sent text-based SMS messages in the SMS app.
    720          */
    721         public static final class Conversations
    722                 implements BaseColumns, TextBasedSmsColumns {
    723 
    724             /**
    725              * Not instantiable.
    726              * @hide
    727              */
    728             private Conversations() {
    729             }
    730 
    731             /**
    732              * The {@code content://} style URL for this table.
    733              */
    734             public static final Uri CONTENT_URI = Uri.parse("content://sms/conversations");
    735 
    736             /**
    737              * The default sort order for this table.
    738              */
    739             public static final String DEFAULT_SORT_ORDER = "date DESC";
    740 
    741             /**
    742              * The first 45 characters of the body of the message.
    743              * <P>Type: TEXT</P>
    744              */
    745             public static final String SNIPPET = "snippet";
    746 
    747             /**
    748              * The number of messages in the conversation.
    749              * <P>Type: INTEGER</P>
    750              */
    751             public static final String MESSAGE_COUNT = "msg_count";
    752         }
    753 
    754         /**
    755          * Contains constants for SMS related Intents that are broadcast.
    756          */
    757         public static final class Intents {
    758 
    759             /**
    760              * Not instantiable.
    761              * @hide
    762              */
    763             private Intents() {
    764             }
    765 
    766             /**
    767              * Set by BroadcastReceiver to indicate that the message was handled
    768              * successfully.
    769              */
    770             public static final int RESULT_SMS_HANDLED = 1;
    771 
    772             /**
    773              * Set by BroadcastReceiver to indicate a generic error while
    774              * processing the message.
    775              */
    776             public static final int RESULT_SMS_GENERIC_ERROR = 2;
    777 
    778             /**
    779              * Set by BroadcastReceiver to indicate insufficient memory to store
    780              * the message.
    781              */
    782             public static final int RESULT_SMS_OUT_OF_MEMORY = 3;
    783 
    784             /**
    785              * Set by BroadcastReceiver to indicate that the message, while
    786              * possibly valid, is of a format or encoding that is not
    787              * supported.
    788              */
    789             public static final int RESULT_SMS_UNSUPPORTED = 4;
    790 
    791             /**
    792              * Set by BroadcastReceiver to indicate a duplicate incoming message.
    793              */
    794             public static final int RESULT_SMS_DUPLICATED = 5;
    795 
    796             /**
    797              * Activity action: Ask the user to change the default
    798              * SMS application. This will show a dialog that asks the
    799              * user whether they want to replace the current default
    800              * SMS application with the one specified in
    801              * {@link #EXTRA_PACKAGE_NAME}.
    802              */
    803             @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    804             public static final String ACTION_CHANGE_DEFAULT =
    805                     "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
    806 
    807             /**
    808              * The PackageName string passed in as an
    809              * extra for {@link #ACTION_CHANGE_DEFAULT}
    810              *
    811              * @see #ACTION_CHANGE_DEFAULT
    812              */
    813             public static final String EXTRA_PACKAGE_NAME = "package";
    814 
    815             /**
    816              * Broadcast Action: A new text-based SMS message has been received
    817              * by the device. This intent will only be delivered to the default
    818              * sms app. That app is responsible for writing the message and notifying
    819              * the user. The intent will have the following extra values:</p>
    820              *
    821              * <ul>
    822              *   <li><em>"pdus"</em> - An Object[] of byte[]s containing the PDUs
    823              *   that make up the message.</li>
    824              * </ul>
    825              *
    826              * <p>The extra values can be extracted using
    827              * {@link #getMessagesFromIntent(Intent)}.</p>
    828              *
    829              * <p>If a BroadcastReceiver encounters an error while processing
    830              * this intent it should set the result code appropriately.</p>
    831              *
    832              * <p class="note"><strong>Note:</strong>
    833              * The broadcast receiver that filters for this intent must declare
    834              * {@link android.Manifest.permission#BROADCAST_SMS} as a required permission in
    835              * the <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code
    836              * &lt;receiver>}</a> tag.
    837              */
    838             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    839             public static final String SMS_DELIVER_ACTION =
    840                     "android.provider.Telephony.SMS_DELIVER";
    841 
    842             /**
    843              * Broadcast Action: A new text-based SMS message has been received
    844              * by the device. This intent will only be delivered to a
    845              * carrier app which is responsible for filtering the message.
    846              * If the carrier app wants to drop a message, it should set the result
    847              * code to {@link android.app.Activity#RESULT_CANCELED}. The carrier app can
    848              * also modify the SMS PDU by setting the "pdus" value in result extras.</p>
    849              *
    850              * The intent will have the following extra values:</p>
    851              *
    852              * <ul>
    853              *   <li><em>"pdus"</em> - An Object[] of byte[]s containing the PDUs
    854              *   that make up the message.</li>
    855              *   <li><em>"format"</em> - A String describing the format of the PDUs. It can
    856              *   be either "3gpp" or "3gpp2".</li>
    857              *   <li><em>"destport"</em> - An int describing the destination port of a data
    858              *   SMS. It will be -1 for text SMS.</li>
    859              * </ul>
    860              *
    861              * <p>The extra values can be extracted using
    862              * {@link #getMessagesFromIntent(Intent)}.</p>
    863              *
    864              * <p class="note"><strong>Note:</strong>
    865              * The broadcast receiver that filters for this intent must be a carrier privileged app.
    866              * It must also declare {@link android.Manifest.permission#BROADCAST_SMS} as a required
    867              * permission in the <a href="{@docRoot}guide/topics/manifest/receiver-element.html">
    868              * {@code &lt;receiver>}</a> tag.
    869              * {@hide}
    870              */
    871             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    872             public static final String SMS_FILTER_ACTION =
    873                     "android.provider.Telephony.SMS_FILTER";
    874 
    875             /**
    876              * Broadcast Action: A new text-based SMS message has been received
    877              * by the device. This intent will be delivered to all registered
    878              * receivers as a notification. These apps are not expected to write the
    879              * message or notify the user. The intent will have the following extra
    880              * values:</p>
    881              *
    882              * <ul>
    883              *   <li><em>"pdus"</em> - An Object[] of byte[]s containing the PDUs
    884              *   that make up the message.</li>
    885              * </ul>
    886              *
    887              * <p>The extra values can be extracted using
    888              * {@link #getMessagesFromIntent(Intent)}.</p>
    889              *
    890              * <p>If a BroadcastReceiver encounters an error while processing
    891              * this intent it should set the result code appropriately.</p>
    892              */
    893             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    894             public static final String SMS_RECEIVED_ACTION =
    895                     "android.provider.Telephony.SMS_RECEIVED";
    896 
    897             /**
    898              * Broadcast Action: A new data based SMS message has been received
    899              * by the device. This intent will be delivered to all registered
    900              * receivers as a notification. The intent will have the following extra
    901              * values:</p>
    902              *
    903              * <ul>
    904              *   <li><em>"pdus"</em> - An Object[] of byte[]s containing the PDUs
    905              *   that make up the message.</li>
    906              * </ul>
    907              *
    908              * <p>The extra values can be extracted using
    909              * {@link #getMessagesFromIntent(Intent)}.</p>
    910              *
    911              * <p>If a BroadcastReceiver encounters an error while processing
    912              * this intent it should set the result code appropriately.</p>
    913              */
    914             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    915             public static final String DATA_SMS_RECEIVED_ACTION =
    916                     "android.intent.action.DATA_SMS_RECEIVED";
    917 
    918             /**
    919              * Broadcast Action: A new WAP PUSH message has been received by the
    920              * device. This intent will only be delivered to the default
    921              * sms app. That app is responsible for writing the message and notifying
    922              * the user. The intent will have the following extra values:</p>
    923              *
    924              * <ul>
    925              *   <li><em>"transactionId"</em> - (Integer) The WAP transaction ID</li>
    926              *   <li><em>"pduType"</em> - (Integer) The WAP PDU type</li>
    927              *   <li><em>"header"</em> - (byte[]) The header of the message</li>
    928              *   <li><em>"data"</em> - (byte[]) The data payload of the message</li>
    929              *   <li><em>"contentTypeParameters" </em>
    930              *   -(HashMap&lt;String,String&gt;) Any parameters associated with the content type
    931              *   (decoded from the WSP Content-Type header)</li>
    932              * </ul>
    933              *
    934              * <p>If a BroadcastReceiver encounters an error while processing
    935              * this intent it should set the result code appropriately.</p>
    936              *
    937              * <p>The contentTypeParameters extra value is map of content parameters keyed by
    938              * their names.</p>
    939              *
    940              * <p>If any unassigned well-known parameters are encountered, the key of the map will
    941              * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter.  If
    942              * a parameter has No-Value the value in the map will be null.</p>
    943              *
    944              * <p class="note"><strong>Note:</strong>
    945              * The broadcast receiver that filters for this intent must declare
    946              * {@link android.Manifest.permission#BROADCAST_WAP_PUSH} as a required permission in
    947              * the <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code
    948              * &lt;receiver>}</a> tag.
    949              */
    950             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    951             public static final String WAP_PUSH_DELIVER_ACTION =
    952                     "android.provider.Telephony.WAP_PUSH_DELIVER";
    953 
    954             /**
    955              * Broadcast Action: A new WAP PUSH message has been received by the
    956              * device. This intent will be delivered to all registered
    957              * receivers as a notification. These apps are not expected to write the
    958              * message or notify the user. The intent will have the following extra
    959              * values:</p>
    960              *
    961              * <ul>
    962              *   <li><em>"transactionId"</em> - (Integer) The WAP transaction ID</li>
    963              *   <li><em>"pduType"</em> - (Integer) The WAP PDU type</li>
    964              *   <li><em>"header"</em> - (byte[]) The header of the message</li>
    965              *   <li><em>"data"</em> - (byte[]) The data payload of the message</li>
    966              *   <li><em>"contentTypeParameters"</em>
    967              *   - (HashMap&lt;String,String&gt;) Any parameters associated with the content type
    968              *   (decoded from the WSP Content-Type header)</li>
    969              * </ul>
    970              *
    971              * <p>If a BroadcastReceiver encounters an error while processing
    972              * this intent it should set the result code appropriately.</p>
    973              *
    974              * <p>The contentTypeParameters extra value is map of content parameters keyed by
    975              * their names.</p>
    976              *
    977              * <p>If any unassigned well-known parameters are encountered, the key of the map will
    978              * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter.  If
    979              * a parameter has No-Value the value in the map will be null.</p>
    980              */
    981             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    982             public static final String WAP_PUSH_RECEIVED_ACTION =
    983                     "android.provider.Telephony.WAP_PUSH_RECEIVED";
    984 
    985             /**
    986              * Broadcast Action: A new Cell Broadcast message has been received
    987              * by the device. The intent will have the following extra
    988              * values:</p>
    989              *
    990              * <ul>
    991              *   <li><em>"message"</em> - An SmsCbMessage object containing the broadcast message
    992              *   data. This is not an emergency alert, so ETWS and CMAS data will be null.</li>
    993              * </ul>
    994              *
    995              * <p>The extra values can be extracted using
    996              * {@link #getMessagesFromIntent(Intent)}.</p>
    997              *
    998              * <p>If a BroadcastReceiver encounters an error while processing
    999              * this intent it should set the result code appropriately.</p>
   1000              */
   1001             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   1002             public static final String SMS_CB_RECEIVED_ACTION =
   1003                     "android.provider.Telephony.SMS_CB_RECEIVED";
   1004 
   1005             /**
   1006              * Broadcast Action: A new Emergency Broadcast message has been received
   1007              * by the device. The intent will have the following extra
   1008              * values:</p>
   1009              *
   1010              * <ul>
   1011              *   <li><em>"message"</em> - An SmsCbMessage object containing the broadcast message
   1012              *   data, including ETWS or CMAS warning notification info if present.</li>
   1013              * </ul>
   1014              *
   1015              * <p>The extra values can be extracted using
   1016              * {@link #getMessagesFromIntent(Intent)}.</p>
   1017              *
   1018              * <p>If a BroadcastReceiver encounters an error while processing
   1019              * this intent it should set the result code appropriately.</p>
   1020              */
   1021             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   1022             public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
   1023                     "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
   1024 
   1025             /**
   1026              * Broadcast Action: A new CDMA SMS has been received containing Service Category
   1027              * Program Data (updates the list of enabled broadcast channels). The intent will
   1028              * have the following extra values:</p>
   1029              *
   1030              * <ul>
   1031              *   <li><em>"operations"</em> - An array of CdmaSmsCbProgramData objects containing
   1032              *   the service category operations (add/delete/clear) to perform.</li>
   1033              * </ul>
   1034              *
   1035              * <p>The extra values can be extracted using
   1036              * {@link #getMessagesFromIntent(Intent)}.</p>
   1037              *
   1038              * <p>If a BroadcastReceiver encounters an error while processing
   1039              * this intent it should set the result code appropriately.</p>
   1040              */
   1041             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   1042             public static final String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION =
   1043                     "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
   1044 
   1045             /**
   1046              * Broadcast Action: The SIM storage for SMS messages is full.  If
   1047              * space is not freed, messages targeted for the SIM (class 2) may
   1048              * not be saved.
   1049              */
   1050             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   1051             public static final String SIM_FULL_ACTION =
   1052                     "android.provider.Telephony.SIM_FULL";
   1053 
   1054             /**
   1055              * Broadcast Action: An incoming SMS has been rejected by the
   1056              * telephony framework.  This intent is sent in lieu of any
   1057              * of the RECEIVED_ACTION intents.  The intent will have the
   1058              * following extra value:</p>
   1059              *
   1060              * <ul>
   1061              *   <li><em>"result"</em> - An int result code, e.g. {@link #RESULT_SMS_OUT_OF_MEMORY}
   1062              *   indicating the error returned to the network.</li>
   1063              * </ul>
   1064              */
   1065             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   1066             public static final String SMS_REJECTED_ACTION =
   1067                 "android.provider.Telephony.SMS_REJECTED";
   1068 
   1069             /**
   1070              * Broadcast Action: A new SMS PDU needs to be sent from
   1071              * the device. This intent will only be delivered to a
   1072              * carrier app. That app is responsible for sending the PDU.
   1073              * The intent will have the following extra values:</p>
   1074              *
   1075              * <ul>
   1076              *   <li><em>"pdu"</em> - (byte[]) The PDU to send.</li>
   1077              *   <li><em>"smsc"</em> - (byte[]) The service center address (for GSM PDU only).</li>
   1078              *   <li><em>"format"</em> - (String) The format of the PDU. Either 3gpp or 3gpp2. </li>
   1079              *   <li><em>"concat.refNumber"</em> - (int) If the SMS is part of a multi-part SMS, the
   1080              *   ref number used in the SMS header.</li>
   1081              *   <li><em>"concat.seqNumber"</em> - (int) If the SMS is part of a multi-part SMS, the
   1082              *   sequence number of this SMS.</li>
   1083              *   <li><em>"concat.msgCount"</em> - (int) If the SMS is part of a multi-part SMS, the
   1084              *   total number of SMSes in the multi-part SMS.</li>
   1085              * </ul>
   1086              *
   1087              * <p>If a BroadcastReceiver is trying to send the message,
   1088              *  it should set the result code to {@link android.app.Activity#RESULT_OK} and set
   1089              *  the following in the result extra values:</p>
   1090              *
   1091              * <ul>
   1092              *   <li><em>"messageref"</em> - (int) The new message reference number which will be
   1093              *   later used in the updateSmsSendStatus call.</li>
   1094              * </ul>
   1095              *
   1096              * <p>If a BroadcastReceiver cannot send the message, it should not set the result
   1097              *  code and the platform will send it via the normal pathway.
   1098              * </p>
   1099              *
   1100              * <p class="note"><strong>Note:</strong>
   1101              * The broadcast receiver that filters for this intent must be a carrier privileged app.
   1102              * It must also declare {@link android.Manifest.permission#BROADCAST_SMS} as a required
   1103              * permission in the <a href="{@docRoot}guide/topics/manifest/receiver-element.html">
   1104              * {@code &lt;receiver>}</a> tag.
   1105              * {@hide}
   1106              */
   1107             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   1108             public static final String SMS_SEND_ACTION =
   1109                 "android.provider.Telephony.SMS_SEND";
   1110 
   1111             /**
   1112              * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
   1113              * {@link #DATA_SMS_RECEIVED_ACTION} intent.
   1114              *
   1115              * @param intent the intent to read from
   1116              * @return an array of SmsMessages for the PDUs
   1117              */
   1118             public static SmsMessage[] getMessagesFromIntent(Intent intent) {
   1119                 Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
   1120                 String format = intent.getStringExtra("format");
   1121                 long subId = intent.getLongExtra(PhoneConstants.SUBSCRIPTION_KEY,
   1122                         SubscriptionManager.getDefaultSmsSubId());
   1123 
   1124                 Rlog.v(TAG, " getMessagesFromIntent sub_id : " + subId);
   1125 
   1126                 int pduCount = messages.length;
   1127                 SmsMessage[] msgs = new SmsMessage[pduCount];
   1128 
   1129                 for (int i = 0; i < pduCount; i++) {
   1130                     byte[] pdu = (byte[]) messages[i];
   1131                     msgs[i] = SmsMessage.createFromPdu(pdu, format);
   1132                     msgs[i].setSubId(subId);
   1133                 }
   1134                 return msgs;
   1135             }
   1136         }
   1137     }
   1138 
   1139     /**
   1140      * Base columns for tables that contain MMSs.
   1141      */
   1142     public interface BaseMmsColumns extends BaseColumns {
   1143 
   1144         /** Message box: all messages. */
   1145         public static final int MESSAGE_BOX_ALL    = 0;
   1146         /** Message box: inbox. */
   1147         public static final int MESSAGE_BOX_INBOX  = 1;
   1148         /** Message box: sent messages. */
   1149         public static final int MESSAGE_BOX_SENT   = 2;
   1150         /** Message box: drafts. */
   1151         public static final int MESSAGE_BOX_DRAFTS = 3;
   1152         /** Message box: outbox. */
   1153         public static final int MESSAGE_BOX_OUTBOX = 4;
   1154         /** Message box: failed. */
   1155         public static final int MESSAGE_BOX_FAILED = 5;
   1156 
   1157         /**
   1158          * The thread ID of the message.
   1159          * <P>Type: INTEGER (long)</P>
   1160          */
   1161         public static final String THREAD_ID = "thread_id";
   1162 
   1163         /**
   1164          * The date the message was received.
   1165          * <P>Type: INTEGER (long)</P>
   1166          */
   1167         public static final String DATE = "date";
   1168 
   1169         /**
   1170          * The date the message was sent.
   1171          * <P>Type: INTEGER (long)</P>
   1172          */
   1173         public static final String DATE_SENT = "date_sent";
   1174 
   1175         /**
   1176          * The box which the message belongs to, e.g. {@link #MESSAGE_BOX_INBOX}.
   1177          * <P>Type: INTEGER</P>
   1178          */
   1179         public static final String MESSAGE_BOX = "msg_box";
   1180 
   1181         /**
   1182          * Has the message been read?
   1183          * <P>Type: INTEGER (boolean)</P>
   1184          */
   1185         public static final String READ = "read";
   1186 
   1187         /**
   1188          * Has the message been seen by the user? The "seen" flag determines
   1189          * whether we need to show a new message notification.
   1190          * <P>Type: INTEGER (boolean)</P>
   1191          */
   1192         public static final String SEEN = "seen";
   1193 
   1194         /**
   1195          * Does the message have only a text part (can also have a subject) with
   1196          * no picture, slideshow, sound, etc. parts?
   1197          * <P>Type: INTEGER (boolean)</P>
   1198          */
   1199         public static final String TEXT_ONLY = "text_only";
   1200 
   1201         /**
   1202          * The {@code Message-ID} of the message.
   1203          * <P>Type: TEXT</P>
   1204          */
   1205         public static final String MESSAGE_ID = "m_id";
   1206 
   1207         /**
   1208          * The subject of the message, if present.
   1209          * <P>Type: TEXT</P>
   1210          */
   1211         public static final String SUBJECT = "sub";
   1212 
   1213         /**
   1214          * The character set of the subject, if present.
   1215          * <P>Type: INTEGER</P>
   1216          */
   1217         public static final String SUBJECT_CHARSET = "sub_cs";
   1218 
   1219         /**
   1220          * The {@code Content-Type} of the message.
   1221          * <P>Type: TEXT</P>
   1222          */
   1223         public static final String CONTENT_TYPE = "ct_t";
   1224 
   1225         /**
   1226          * The {@code Content-Location} of the message.
   1227          * <P>Type: TEXT</P>
   1228          */
   1229         public static final String CONTENT_LOCATION = "ct_l";
   1230 
   1231         /**
   1232          * The expiry time of the message.
   1233          * <P>Type: INTEGER (long)</P>
   1234          */
   1235         public static final String EXPIRY = "exp";
   1236 
   1237         /**
   1238          * The class of the message.
   1239          * <P>Type: TEXT</P>
   1240          */
   1241         public static final String MESSAGE_CLASS = "m_cls";
   1242 
   1243         /**
   1244          * The type of the message defined by MMS spec.
   1245          * <P>Type: INTEGER</P>
   1246          */
   1247         public static final String MESSAGE_TYPE = "m_type";
   1248 
   1249         /**
   1250          * The version of the specification that this message conforms to.
   1251          * <P>Type: INTEGER</P>
   1252          */
   1253         public static final String MMS_VERSION = "v";
   1254 
   1255         /**
   1256          * The size of the message.
   1257          * <P>Type: INTEGER</P>
   1258          */
   1259         public static final String MESSAGE_SIZE = "m_size";
   1260 
   1261         /**
   1262          * The priority of the message.
   1263          * <P>Type: INTEGER</P>
   1264          */
   1265         public static final String PRIORITY = "pri";
   1266 
   1267         /**
   1268          * The {@code read-report} of the message.
   1269          * <P>Type: INTEGER (boolean)</P>
   1270          */
   1271         public static final String READ_REPORT = "rr";
   1272 
   1273         /**
   1274          * Is read report allowed?
   1275          * <P>Type: INTEGER (boolean)</P>
   1276          */
   1277         public static final String REPORT_ALLOWED = "rpt_a";
   1278 
   1279         /**
   1280          * The {@code response-status} of the message.
   1281          * <P>Type: INTEGER</P>
   1282          */
   1283         public static final String RESPONSE_STATUS = "resp_st";
   1284 
   1285         /**
   1286          * The {@code status} of the message.
   1287          * <P>Type: INTEGER</P>
   1288          */
   1289         public static final String STATUS = "st";
   1290 
   1291         /**
   1292          * The {@code transaction-id} of the message.
   1293          * <P>Type: TEXT</P>
   1294          */
   1295         public static final String TRANSACTION_ID = "tr_id";
   1296 
   1297         /**
   1298          * The {@code retrieve-status} of the message.
   1299          * <P>Type: INTEGER</P>
   1300          */
   1301         public static final String RETRIEVE_STATUS = "retr_st";
   1302 
   1303         /**
   1304          * The {@code retrieve-text} of the message.
   1305          * <P>Type: TEXT</P>
   1306          */
   1307         public static final String RETRIEVE_TEXT = "retr_txt";
   1308 
   1309         /**
   1310          * The character set of the retrieve-text.
   1311          * <P>Type: INTEGER</P>
   1312          */
   1313         public static final String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
   1314 
   1315         /**
   1316          * The {@code read-status} of the message.
   1317          * <P>Type: INTEGER</P>
   1318          */
   1319         public static final String READ_STATUS = "read_status";
   1320 
   1321         /**
   1322          * The {@code content-class} of the message.
   1323          * <P>Type: INTEGER</P>
   1324          */
   1325         public static final String CONTENT_CLASS = "ct_cls";
   1326 
   1327         /**
   1328          * The {@code delivery-report} of the message.
   1329          * <P>Type: INTEGER</P>
   1330          */
   1331         public static final String DELIVERY_REPORT = "d_rpt";
   1332 
   1333         /**
   1334          * The {@code delivery-time-token} of the message.
   1335          * <P>Type: INTEGER</P>
   1336          * @deprecated this column is no longer supported.
   1337          * @hide
   1338          */
   1339         @Deprecated
   1340         public static final String DELIVERY_TIME_TOKEN = "d_tm_tok";
   1341 
   1342         /**
   1343          * The {@code delivery-time} of the message.
   1344          * <P>Type: INTEGER</P>
   1345          */
   1346         public static final String DELIVERY_TIME = "d_tm";
   1347 
   1348         /**
   1349          * The {@code response-text} of the message.
   1350          * <P>Type: TEXT</P>
   1351          */
   1352         public static final String RESPONSE_TEXT = "resp_txt";
   1353 
   1354         /**
   1355          * The {@code sender-visibility} of the message.
   1356          * <P>Type: TEXT</P>
   1357          * @deprecated this column is no longer supported.
   1358          * @hide
   1359          */
   1360         @Deprecated
   1361         public static final String SENDER_VISIBILITY = "s_vis";
   1362 
   1363         /**
   1364          * The {@code reply-charging} of the message.
   1365          * <P>Type: INTEGER</P>
   1366          * @deprecated this column is no longer supported.
   1367          * @hide
   1368          */
   1369         @Deprecated
   1370         public static final String REPLY_CHARGING = "r_chg";
   1371 
   1372         /**
   1373          * The {@code reply-charging-deadline-token} of the message.
   1374          * <P>Type: INTEGER</P>
   1375          * @deprecated this column is no longer supported.
   1376          * @hide
   1377          */
   1378         @Deprecated
   1379         public static final String REPLY_CHARGING_DEADLINE_TOKEN = "r_chg_dl_tok";
   1380 
   1381         /**
   1382          * The {@code reply-charging-deadline} of the message.
   1383          * <P>Type: INTEGER</P>
   1384          * @deprecated this column is no longer supported.
   1385          * @hide
   1386          */
   1387         @Deprecated
   1388         public static final String REPLY_CHARGING_DEADLINE = "r_chg_dl";
   1389 
   1390         /**
   1391          * The {@code reply-charging-id} of the message.
   1392          * <P>Type: TEXT</P>
   1393          * @deprecated this column is no longer supported.
   1394          * @hide
   1395          */
   1396         @Deprecated
   1397         public static final String REPLY_CHARGING_ID = "r_chg_id";
   1398 
   1399         /**
   1400          * The {@code reply-charging-size} of the message.
   1401          * <P>Type: INTEGER</P>
   1402          * @deprecated this column is no longer supported.
   1403          * @hide
   1404          */
   1405         @Deprecated
   1406         public static final String REPLY_CHARGING_SIZE = "r_chg_sz";
   1407 
   1408         /**
   1409          * The {@code previously-sent-by} of the message.
   1410          * <P>Type: TEXT</P>
   1411          * @deprecated this column is no longer supported.
   1412          * @hide
   1413          */
   1414         @Deprecated
   1415         public static final String PREVIOUSLY_SENT_BY = "p_s_by";
   1416 
   1417         /**
   1418          * The {@code previously-sent-date} of the message.
   1419          * <P>Type: INTEGER</P>
   1420          * @deprecated this column is no longer supported.
   1421          * @hide
   1422          */
   1423         @Deprecated
   1424         public static final String PREVIOUSLY_SENT_DATE = "p_s_d";
   1425 
   1426         /**
   1427          * The {@code store} of the message.
   1428          * <P>Type: TEXT</P>
   1429          * @deprecated this column is no longer supported.
   1430          * @hide
   1431          */
   1432         @Deprecated
   1433         public static final String STORE = "store";
   1434 
   1435         /**
   1436          * The {@code mm-state} of the message.
   1437          * <P>Type: INTEGER</P>
   1438          * @deprecated this column is no longer supported.
   1439          * @hide
   1440          */
   1441         @Deprecated
   1442         public static final String MM_STATE = "mm_st";
   1443 
   1444         /**
   1445          * The {@code mm-flags-token} of the message.
   1446          * <P>Type: INTEGER</P>
   1447          * @deprecated this column is no longer supported.
   1448          * @hide
   1449          */
   1450         @Deprecated
   1451         public static final String MM_FLAGS_TOKEN = "mm_flg_tok";
   1452 
   1453         /**
   1454          * The {@code mm-flags} of the message.
   1455          * <P>Type: TEXT</P>
   1456          * @deprecated this column is no longer supported.
   1457          * @hide
   1458          */
   1459         @Deprecated
   1460         public static final String MM_FLAGS = "mm_flg";
   1461 
   1462         /**
   1463          * The {@code store-status} of the message.
   1464          * <P>Type: TEXT</P>
   1465          * @deprecated this column is no longer supported.
   1466          * @hide
   1467          */
   1468         @Deprecated
   1469         public static final String STORE_STATUS = "store_st";
   1470 
   1471         /**
   1472          * The {@code store-status-text} of the message.
   1473          * <P>Type: TEXT</P>
   1474          * @deprecated this column is no longer supported.
   1475          * @hide
   1476          */
   1477         @Deprecated
   1478         public static final String STORE_STATUS_TEXT = "store_st_txt";
   1479 
   1480         /**
   1481          * The {@code stored} of the message.
   1482          * <P>Type: TEXT</P>
   1483          * @deprecated this column is no longer supported.
   1484          * @hide
   1485          */
   1486         @Deprecated
   1487         public static final String STORED = "stored";
   1488 
   1489         /**
   1490          * The {@code totals} of the message.
   1491          * <P>Type: TEXT</P>
   1492          * @deprecated this column is no longer supported.
   1493          * @hide
   1494          */
   1495         @Deprecated
   1496         public static final String TOTALS = "totals";
   1497 
   1498         /**
   1499          * The {@code mbox-totals} of the message.
   1500          * <P>Type: TEXT</P>
   1501          * @deprecated this column is no longer supported.
   1502          * @hide
   1503          */
   1504         @Deprecated
   1505         public static final String MBOX_TOTALS = "mb_t";
   1506 
   1507         /**
   1508          * The {@code mbox-totals-token} of the message.
   1509          * <P>Type: INTEGER</P>
   1510          * @deprecated this column is no longer supported.
   1511          * @hide
   1512          */
   1513         @Deprecated
   1514         public static final String MBOX_TOTALS_TOKEN = "mb_t_tok";
   1515 
   1516         /**
   1517          * The {@code quotas} of the message.
   1518          * <P>Type: TEXT</P>
   1519          * @deprecated this column is no longer supported.
   1520          * @hide
   1521          */
   1522         @Deprecated
   1523         public static final String QUOTAS = "qt";
   1524 
   1525         /**
   1526          * The {@code mbox-quotas} of the message.
   1527          * <P>Type: TEXT</P>
   1528          * @deprecated this column is no longer supported.
   1529          * @hide
   1530          */
   1531         @Deprecated
   1532         public static final String MBOX_QUOTAS = "mb_qt";
   1533 
   1534         /**
   1535          * The {@code mbox-quotas-token} of the message.
   1536          * <P>Type: INTEGER</P>
   1537          * @deprecated this column is no longer supported.
   1538          * @hide
   1539          */
   1540         @Deprecated
   1541         public static final String MBOX_QUOTAS_TOKEN = "mb_qt_tok";
   1542 
   1543         /**
   1544          * The {@code message-count} of the message.
   1545          * <P>Type: INTEGER</P>
   1546          * @deprecated this column is no longer supported.
   1547          * @hide
   1548          */
   1549         @Deprecated
   1550         public static final String MESSAGE_COUNT = "m_cnt";
   1551 
   1552         /**
   1553          * The {@code start} of the message.
   1554          * <P>Type: INTEGER</P>
   1555          * @deprecated this column is no longer supported.
   1556          * @hide
   1557          */
   1558         @Deprecated
   1559         public static final String START = "start";
   1560 
   1561         /**
   1562          * The {@code distribution-indicator} of the message.
   1563          * <P>Type: TEXT</P>
   1564          * @deprecated this column is no longer supported.
   1565          * @hide
   1566          */
   1567         @Deprecated
   1568         public static final String DISTRIBUTION_INDICATOR = "d_ind";
   1569 
   1570         /**
   1571          * The {@code element-descriptor} of the message.
   1572          * <P>Type: TEXT</P>
   1573          * @deprecated this column is no longer supported.
   1574          * @hide
   1575          */
   1576         @Deprecated
   1577         public static final String ELEMENT_DESCRIPTOR = "e_des";
   1578 
   1579         /**
   1580          * The {@code limit} of the message.
   1581          * <P>Type: INTEGER</P>
   1582          * @deprecated this column is no longer supported.
   1583          * @hide
   1584          */
   1585         @Deprecated
   1586         public static final String LIMIT = "limit";
   1587 
   1588         /**
   1589          * The {@code recommended-retrieval-mode} of the message.
   1590          * <P>Type: INTEGER</P>
   1591          * @deprecated this column is no longer supported.
   1592          * @hide
   1593          */
   1594         @Deprecated
   1595         public static final String RECOMMENDED_RETRIEVAL_MODE = "r_r_mod";
   1596 
   1597         /**
   1598          * The {@code recommended-retrieval-mode-text} of the message.
   1599          * <P>Type: TEXT</P>
   1600          * @deprecated this column is no longer supported.
   1601          * @hide
   1602          */
   1603         @Deprecated
   1604         public static final String RECOMMENDED_RETRIEVAL_MODE_TEXT = "r_r_mod_txt";
   1605 
   1606         /**
   1607          * The {@code status-text} of the message.
   1608          * <P>Type: TEXT</P>
   1609          * @deprecated this column is no longer supported.
   1610          * @hide
   1611          */
   1612         @Deprecated
   1613         public static final String STATUS_TEXT = "st_txt";
   1614 
   1615         /**
   1616          * The {@code applic-id} of the message.
   1617          * <P>Type: TEXT</P>
   1618          * @deprecated this column is no longer supported.
   1619          * @hide
   1620          */
   1621         @Deprecated
   1622         public static final String APPLIC_ID = "apl_id";
   1623 
   1624         /**
   1625          * The {@code reply-applic-id} of the message.
   1626          * <P>Type: TEXT</P>
   1627          * @deprecated this column is no longer supported.
   1628          * @hide
   1629          */
   1630         @Deprecated
   1631         public static final String REPLY_APPLIC_ID = "r_apl_id";
   1632 
   1633         /**
   1634          * The {@code aux-applic-id} of the message.
   1635          * <P>Type: TEXT</P>
   1636          * @deprecated this column is no longer supported.
   1637          * @hide
   1638          */
   1639         @Deprecated
   1640         public static final String AUX_APPLIC_ID = "aux_apl_id";
   1641 
   1642         /**
   1643          * The {@code drm-content} of the message.
   1644          * <P>Type: TEXT</P>
   1645          * @deprecated this column is no longer supported.
   1646          * @hide
   1647          */
   1648         @Deprecated
   1649         public static final String DRM_CONTENT = "drm_c";
   1650 
   1651         /**
   1652          * The {@code adaptation-allowed} of the message.
   1653          * <P>Type: TEXT</P>
   1654          * @deprecated this column is no longer supported.
   1655          * @hide
   1656          */
   1657         @Deprecated
   1658         public static final String ADAPTATION_ALLOWED = "adp_a";
   1659 
   1660         /**
   1661          * The {@code replace-id} of the message.
   1662          * <P>Type: TEXT</P>
   1663          * @deprecated this column is no longer supported.
   1664          * @hide
   1665          */
   1666         @Deprecated
   1667         public static final String REPLACE_ID = "repl_id";
   1668 
   1669         /**
   1670          * The {@code cancel-id} of the message.
   1671          * <P>Type: TEXT</P>
   1672          * @deprecated this column is no longer supported.
   1673          * @hide
   1674          */
   1675         @Deprecated
   1676         public static final String CANCEL_ID = "cl_id";
   1677 
   1678         /**
   1679          * The {@code cancel-status} of the message.
   1680          * <P>Type: INTEGER</P>
   1681          * @deprecated this column is no longer supported.
   1682          * @hide
   1683          */
   1684         @Deprecated
   1685         public static final String CANCEL_STATUS = "cl_st";
   1686 
   1687         /**
   1688          * Is the message locked?
   1689          * <P>Type: INTEGER (boolean)</P>
   1690          */
   1691         public static final String LOCKED = "locked";
   1692 
   1693         /**
   1694          * The sub id to which message belongs to
   1695          * <p>Type: INTEGER</p>
   1696          * @hide
   1697          */
   1698         public static final String SUB_ID = "sub_id";
   1699 
   1700         /**
   1701          * The identity of the sender of a sent message. It is
   1702          * usually the package name of the app which sends the message.
   1703          * <p>Type: TEXT</p>
   1704          */
   1705         public static final String CREATOR = "creator";
   1706     }
   1707 
   1708     /**
   1709      * Columns for the "canonical_addresses" table used by MMS and SMS.
   1710      */
   1711     public interface CanonicalAddressesColumns extends BaseColumns {
   1712         /**
   1713          * An address used in MMS or SMS.  Email addresses are
   1714          * converted to lower case and are compared by string
   1715          * equality.  Other addresses are compared using
   1716          * PHONE_NUMBERS_EQUAL.
   1717          * <P>Type: TEXT</P>
   1718          */
   1719         public static final String ADDRESS = "address";
   1720     }
   1721 
   1722     /**
   1723      * Columns for the "threads" table used by MMS and SMS.
   1724      */
   1725     public interface ThreadsColumns extends BaseColumns {
   1726 
   1727         /**
   1728          * The date at which the thread was created.
   1729          * <P>Type: INTEGER (long)</P>
   1730          */
   1731         public static final String DATE = "date";
   1732 
   1733         /**
   1734          * A string encoding of the recipient IDs of the recipients of
   1735          * the message, in numerical order and separated by spaces.
   1736          * <P>Type: TEXT</P>
   1737          */
   1738         public static final String RECIPIENT_IDS = "recipient_ids";
   1739 
   1740         /**
   1741          * The message count of the thread.
   1742          * <P>Type: INTEGER</P>
   1743          */
   1744         public static final String MESSAGE_COUNT = "message_count";
   1745 
   1746         /**
   1747          * Indicates whether all messages of the thread have been read.
   1748          * <P>Type: INTEGER</P>
   1749          */
   1750         public static final String READ = "read";
   1751 
   1752         /**
   1753          * The snippet of the latest message in the thread.
   1754          * <P>Type: TEXT</P>
   1755          */
   1756         public static final String SNIPPET = "snippet";
   1757 
   1758         /**
   1759          * The charset of the snippet.
   1760          * <P>Type: INTEGER</P>
   1761          */
   1762         public static final String SNIPPET_CHARSET = "snippet_cs";
   1763 
   1764         /**
   1765          * Type of the thread, either {@link Threads#COMMON_THREAD} or
   1766          * {@link Threads#BROADCAST_THREAD}.
   1767          * <P>Type: INTEGER</P>
   1768          */
   1769         public static final String TYPE = "type";
   1770 
   1771         /**
   1772          * Indicates whether there is a transmission error in the thread.
   1773          * <P>Type: INTEGER</P>
   1774          */
   1775         public static final String ERROR = "error";
   1776 
   1777         /**
   1778          * Indicates whether this thread contains any attachments.
   1779          * <P>Type: INTEGER</P>
   1780          */
   1781         public static final String HAS_ATTACHMENT = "has_attachment";
   1782 
   1783         /**
   1784          * If the thread is archived
   1785          * <P>Type: INTEGER (boolean)</P>
   1786          */
   1787         public static final String ARCHIVED = "archived";
   1788     }
   1789 
   1790     /**
   1791      * Helper functions for the "threads" table used by MMS and SMS.
   1792      */
   1793     public static final class Threads implements ThreadsColumns {
   1794 
   1795         private static final String[] ID_PROJECTION = { BaseColumns._ID };
   1796 
   1797         /**
   1798          * Private {@code content://} style URL for this table. Used by
   1799          * {@link #getOrCreateThreadId(android.content.Context, java.util.Set)}.
   1800          */
   1801         private static final Uri THREAD_ID_CONTENT_URI = Uri.parse(
   1802                 "content://mms-sms/threadID");
   1803 
   1804         /**
   1805          * The {@code content://} style URL for this table, by conversation.
   1806          */
   1807         public static final Uri CONTENT_URI = Uri.withAppendedPath(
   1808                 MmsSms.CONTENT_URI, "conversations");
   1809 
   1810         /**
   1811          * The {@code content://} style URL for this table, for obsolete threads.
   1812          */
   1813         public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(
   1814                 CONTENT_URI, "obsolete");
   1815 
   1816         /** Thread type: common thread. */
   1817         public static final int COMMON_THREAD    = 0;
   1818 
   1819         /** Thread type: broadcast thread. */
   1820         public static final int BROADCAST_THREAD = 1;
   1821 
   1822         /**
   1823          * Not instantiable.
   1824          * @hide
   1825          */
   1826         private Threads() {
   1827         }
   1828 
   1829         /**
   1830          * This is a single-recipient version of {@code getOrCreateThreadId}.
   1831          * It's convenient for use with SMS messages.
   1832          * @param context the context object to use.
   1833          * @param recipient the recipient to send to.
   1834          * @hide
   1835          */
   1836         public static long getOrCreateThreadId(Context context, String recipient) {
   1837             Set<String> recipients = new HashSet<String>();
   1838 
   1839             recipients.add(recipient);
   1840             return getOrCreateThreadId(context, recipients);
   1841         }
   1842 
   1843         /**
   1844          * Given the recipients list and subject of an unsaved message,
   1845          * return its thread ID.  If the message starts a new thread,
   1846          * allocate a new thread ID.  Otherwise, use the appropriate
   1847          * existing thread ID.
   1848          *
   1849          * <p>Find the thread ID of the same set of recipients (in any order,
   1850          * without any additions). If one is found, return it. Otherwise,
   1851          * return a unique thread ID.</p>
   1852          * @hide
   1853          */
   1854         public static long getOrCreateThreadId(
   1855                 Context context, Set<String> recipients) {
   1856             Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();
   1857 
   1858             for (String recipient : recipients) {
   1859                 if (Mms.isEmailAddress(recipient)) {
   1860                     recipient = Mms.extractAddrSpec(recipient);
   1861                 }
   1862 
   1863                 uriBuilder.appendQueryParameter("recipient", recipient);
   1864             }
   1865 
   1866             Uri uri = uriBuilder.build();
   1867             //if (DEBUG) Rlog.v(TAG, "getOrCreateThreadId uri: " + uri);
   1868 
   1869             Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
   1870                     uri, ID_PROJECTION, null, null, null);
   1871             if (cursor != null) {
   1872                 try {
   1873                     if (cursor.moveToFirst()) {
   1874                         return cursor.getLong(0);
   1875                     } else {
   1876                         Rlog.e(TAG, "getOrCreateThreadId returned no rows!");
   1877                     }
   1878                 } finally {
   1879                     cursor.close();
   1880                 }
   1881             }
   1882 
   1883             Rlog.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString());
   1884             throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
   1885         }
   1886     }
   1887 
   1888     /**
   1889      * Contains all MMS messages.
   1890      */
   1891     public static final class Mms implements BaseMmsColumns {
   1892 
   1893         /**
   1894          * Not instantiable.
   1895          * @hide
   1896          */
   1897         private Mms() {
   1898         }
   1899 
   1900         /**
   1901          * The {@code content://} URI for this table.
   1902          */
   1903         public static final Uri CONTENT_URI = Uri.parse("content://mms");
   1904 
   1905         /**
   1906          * Content URI for getting MMS report requests.
   1907          */
   1908         public static final Uri REPORT_REQUEST_URI = Uri.withAppendedPath(
   1909                                             CONTENT_URI, "report-request");
   1910 
   1911         /**
   1912          * Content URI for getting MMS report status.
   1913          */
   1914         public static final Uri REPORT_STATUS_URI = Uri.withAppendedPath(
   1915                                             CONTENT_URI, "report-status");
   1916 
   1917         /**
   1918          * The default sort order for this table.
   1919          */
   1920         public static final String DEFAULT_SORT_ORDER = "date DESC";
   1921 
   1922         /**
   1923          * Regex pattern for names and email addresses.
   1924          * <ul>
   1925          *     <li><em>mailbox</em> = {@code name-addr}</li>
   1926          *     <li><em>name-addr</em> = {@code [display-name] angle-addr}</li>
   1927          *     <li><em>angle-addr</em> = {@code [CFWS] "<" addr-spec ">" [CFWS]}</li>
   1928          * </ul>
   1929          * @hide
   1930          */
   1931         public static final Pattern NAME_ADDR_EMAIL_PATTERN =
   1932                 Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");
   1933 
   1934         /**
   1935          * Helper method to query this table.
   1936          * @hide
   1937          */
   1938         public static Cursor query(
   1939                 ContentResolver cr, String[] projection) {
   1940             return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
   1941         }
   1942 
   1943         /**
   1944          * Helper method to query this table.
   1945          * @hide
   1946          */
   1947         public static Cursor query(
   1948                 ContentResolver cr, String[] projection,
   1949                 String where, String orderBy) {
   1950             return cr.query(CONTENT_URI, projection,
   1951                     where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
   1952         }
   1953 
   1954         /**
   1955          * Helper method to extract email address from address string.
   1956          * @hide
   1957          */
   1958         public static String extractAddrSpec(String address) {
   1959             Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);
   1960 
   1961             if (match.matches()) {
   1962                 return match.group(2);
   1963             }
   1964             return address;
   1965         }
   1966 
   1967         /**
   1968          * Is the specified address an email address?
   1969          *
   1970          * @param address the input address to test
   1971          * @return true if address is an email address; false otherwise.
   1972          * @hide
   1973          */
   1974         public static boolean isEmailAddress(String address) {
   1975             if (TextUtils.isEmpty(address)) {
   1976                 return false;
   1977             }
   1978 
   1979             String s = extractAddrSpec(address);
   1980             Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
   1981             return match.matches();
   1982         }
   1983 
   1984         /**
   1985          * Is the specified number a phone number?
   1986          *
   1987          * @param number the input number to test
   1988          * @return true if number is a phone number; false otherwise.
   1989          * @hide
   1990          */
   1991         public static boolean isPhoneNumber(String number) {
   1992             if (TextUtils.isEmpty(number)) {
   1993                 return false;
   1994             }
   1995 
   1996             Matcher match = Patterns.PHONE.matcher(number);
   1997             return match.matches();
   1998         }
   1999 
   2000         /**
   2001          * Contains all MMS messages in the MMS app inbox.
   2002          */
   2003         public static final class Inbox implements BaseMmsColumns {
   2004 
   2005             /**
   2006              * Not instantiable.
   2007              * @hide
   2008              */
   2009             private Inbox() {
   2010             }
   2011 
   2012             /**
   2013              * The {@code content://} style URL for this table.
   2014              */
   2015             public static final Uri
   2016                     CONTENT_URI = Uri.parse("content://mms/inbox");
   2017 
   2018             /**
   2019              * The default sort order for this table.
   2020              */
   2021             public static final String DEFAULT_SORT_ORDER = "date DESC";
   2022         }
   2023 
   2024         /**
   2025          * Contains all MMS messages in the MMS app sent folder.
   2026          */
   2027         public static final class Sent implements BaseMmsColumns {
   2028 
   2029             /**
   2030              * Not instantiable.
   2031              * @hide
   2032              */
   2033             private Sent() {
   2034             }
   2035 
   2036             /**
   2037              * The {@code content://} style URL for this table.
   2038              */
   2039             public static final Uri
   2040                     CONTENT_URI = Uri.parse("content://mms/sent");
   2041 
   2042             /**
   2043              * The default sort order for this table.
   2044              */
   2045             public static final String DEFAULT_SORT_ORDER = "date DESC";
   2046         }
   2047 
   2048         /**
   2049          * Contains all MMS messages in the MMS app drafts folder.
   2050          */
   2051         public static final class Draft implements BaseMmsColumns {
   2052 
   2053             /**
   2054              * Not instantiable.
   2055              * @hide
   2056              */
   2057             private Draft() {
   2058             }
   2059 
   2060             /**
   2061              * The {@code content://} style URL for this table.
   2062              */
   2063             public static final Uri
   2064                     CONTENT_URI = Uri.parse("content://mms/drafts");
   2065 
   2066             /**
   2067              * The default sort order for this table.
   2068              */
   2069             public static final String DEFAULT_SORT_ORDER = "date DESC";
   2070         }
   2071 
   2072         /**
   2073          * Contains all MMS messages in the MMS app outbox.
   2074          */
   2075         public static final class Outbox implements BaseMmsColumns {
   2076 
   2077             /**
   2078              * Not instantiable.
   2079              * @hide
   2080              */
   2081             private Outbox() {
   2082             }
   2083 
   2084             /**
   2085              * The {@code content://} style URL for this table.
   2086              */
   2087             public static final Uri
   2088                     CONTENT_URI = Uri.parse("content://mms/outbox");
   2089 
   2090             /**
   2091              * The default sort order for this table.
   2092              */
   2093             public static final String DEFAULT_SORT_ORDER = "date DESC";
   2094         }
   2095 
   2096         /**
   2097          * Contains address information for an MMS message.
   2098          */
   2099         public static final class Addr implements BaseColumns {
   2100 
   2101             /**
   2102              * Not instantiable.
   2103              * @hide
   2104              */
   2105             private Addr() {
   2106             }
   2107 
   2108             /**
   2109              * The ID of MM which this address entry belongs to.
   2110              * <P>Type: INTEGER (long)</P>
   2111              */
   2112             public static final String MSG_ID = "msg_id";
   2113 
   2114             /**
   2115              * The ID of contact entry in Phone Book.
   2116              * <P>Type: INTEGER (long)</P>
   2117              */
   2118             public static final String CONTACT_ID = "contact_id";
   2119 
   2120             /**
   2121              * The address text.
   2122              * <P>Type: TEXT</P>
   2123              */
   2124             public static final String ADDRESS = "address";
   2125 
   2126             /**
   2127              * Type of address: must be one of {@code PduHeaders.BCC},
   2128              * {@code PduHeaders.CC}, {@code PduHeaders.FROM}, {@code PduHeaders.TO}.
   2129              * <P>Type: INTEGER</P>
   2130              */
   2131             public static final String TYPE = "type";
   2132 
   2133             /**
   2134              * Character set of this entry (MMS charset value).
   2135              * <P>Type: INTEGER</P>
   2136              */
   2137             public static final String CHARSET = "charset";
   2138         }
   2139 
   2140         /**
   2141          * Contains message parts.
   2142          */
   2143         public static final class Part implements BaseColumns {
   2144 
   2145             /**
   2146              * Not instantiable.
   2147              * @hide
   2148              */
   2149             private Part() {
   2150             }
   2151 
   2152             /**
   2153              * The identifier of the message which this part belongs to.
   2154              * <P>Type: INTEGER</P>
   2155              */
   2156             public static final String MSG_ID = "mid";
   2157 
   2158             /**
   2159              * The order of the part.
   2160              * <P>Type: INTEGER</P>
   2161              */
   2162             public static final String SEQ = "seq";
   2163 
   2164             /**
   2165              * The content type of the part.
   2166              * <P>Type: TEXT</P>
   2167              */
   2168             public static final String CONTENT_TYPE = "ct";
   2169 
   2170             /**
   2171              * The name of the part.
   2172              * <P>Type: TEXT</P>
   2173              */
   2174             public static final String NAME = "name";
   2175 
   2176             /**
   2177              * The charset of the part.
   2178              * <P>Type: TEXT</P>
   2179              */
   2180             public static final String CHARSET = "chset";
   2181 
   2182             /**
   2183              * The file name of the part.
   2184              * <P>Type: TEXT</P>
   2185              */
   2186             public static final String FILENAME = "fn";
   2187 
   2188             /**
   2189              * The content disposition of the part.
   2190              * <P>Type: TEXT</P>
   2191              */
   2192             public static final String CONTENT_DISPOSITION = "cd";
   2193 
   2194             /**
   2195              * The content ID of the part.
   2196              * <P>Type: INTEGER</P>
   2197              */
   2198             public static final String CONTENT_ID = "cid";
   2199 
   2200             /**
   2201              * The content location of the part.
   2202              * <P>Type: INTEGER</P>
   2203              */
   2204             public static final String CONTENT_LOCATION = "cl";
   2205 
   2206             /**
   2207              * The start of content-type of the message.
   2208              * <P>Type: INTEGER</P>
   2209              */
   2210             public static final String CT_START = "ctt_s";
   2211 
   2212             /**
   2213              * The type of content-type of the message.
   2214              * <P>Type: TEXT</P>
   2215              */
   2216             public static final String CT_TYPE = "ctt_t";
   2217 
   2218             /**
   2219              * The location (on filesystem) of the binary data of the part.
   2220              * <P>Type: INTEGER</P>
   2221              */
   2222             public static final String _DATA = "_data";
   2223 
   2224             /**
   2225              * The message text.
   2226              * <P>Type: TEXT</P>
   2227              */
   2228             public static final String TEXT = "text";
   2229         }
   2230 
   2231         /**
   2232          * Message send rate table.
   2233          */
   2234         public static final class Rate {
   2235 
   2236             /**
   2237              * Not instantiable.
   2238              * @hide
   2239              */
   2240             private Rate() {
   2241             }
   2242 
   2243             /**
   2244              * The {@code content://} style URL for this table.
   2245              */
   2246             public static final Uri CONTENT_URI = Uri.withAppendedPath(
   2247                     Mms.CONTENT_URI, "rate");
   2248 
   2249             /**
   2250              * When a message was successfully sent.
   2251              * <P>Type: INTEGER (long)</P>
   2252              */
   2253             public static final String SENT_TIME = "sent_time";
   2254         }
   2255 
   2256         /**
   2257          * Intents class.
   2258          */
   2259         public static final class Intents {
   2260 
   2261             /**
   2262              * Not instantiable.
   2263              * @hide
   2264              */
   2265             private Intents() {
   2266             }
   2267 
   2268             /**
   2269              * Indicates that the contents of specified URIs were changed.
   2270              * The application which is showing or caching these contents
   2271              * should be updated.
   2272              */
   2273             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   2274             public static final String CONTENT_CHANGED_ACTION
   2275                     = "android.intent.action.CONTENT_CHANGED";
   2276 
   2277             /**
   2278              * Broadcast Action: A new MMS PDU needs to be sent from
   2279              * the device. This intent will only be delivered to a
   2280              * carrier app. That app is responsible for sending the PDU.
   2281              * The intent will have the following extra values:</p>
   2282              *
   2283              * <ul>
   2284              *   <li><em>{@link #EXTRA_MMS_CONTENT_URI}</em> - (Uri) The content provider of the
   2285              *     PDU to send.</li>
   2286              *   <li><em>{@link #EXTRA_MMS_LOCATION_URL}</em> - (String) The optional url to send
   2287              *     this MMS PDU. If this is not specified, PDU should be sent to the default MMSC
   2288              *     url.</li>
   2289              * </ul>
   2290              *
   2291              * <p>If a BroadcastReceiver is trying to send the message,
   2292              *  it should set the result code to {@link android.app.Activity#RESULT_OK} and set
   2293              *  the following in the result extra values:</p>
   2294              *
   2295              * <ul>
   2296              *   <li><em>"messageref"</em> - (int) The new message reference number which will be
   2297              *   later used in the updateMmsSendStatus call.</li>
   2298              * </ul>
   2299              *
   2300              * <p>If a BroadcastReceiver cannot send the message, it should not set the result
   2301              *  code and the platform will send it via the normal pathway.
   2302              * </p>
   2303              *
   2304              * <p class="note"><strong>Note:</strong>
   2305              * The broadcast receiver that filters for this intent must be a carrier privileged app.
   2306              * It must also declare {@link android.Manifest.permission#BROADCAST_WAP_PUSH} as a required
   2307              * permission in the <a href="{@docRoot}guide/topics/manifest/receiver-element.html">
   2308              * {@code &lt;receiver>}</a> tag.
   2309              * {@hide}
   2310              */
   2311             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   2312             public static final String MMS_SEND_ACTION =
   2313                     "android.provider.Telephony.MMS_SEND";
   2314 
   2315             /**
   2316              * Broadcast Action: A new MMS needs to be downloaded.
   2317              * This intent will only be delivered to a
   2318              * carrier app. That app is responsible for downloading the message at the URL.
   2319              * The intent will have the following extra values:</p>
   2320              *
   2321              * <ul>
   2322              *   <li><em>{@link #EXTRA_MMS_CONTENT_URI}</em> - (Uri) The content provider of the
   2323              *     PDU to be downloaded.</li>
   2324              *   <li><em>{@link #EXTRA_MMS_LOCATION_URL}</em> - (String) The message URL to be
   2325              *     downloaded.</li>
   2326              * </ul>
   2327              *
   2328              * <p>If a BroadcastReceiver is trying to download the message,
   2329              *  it should set the result code to {@link android.app.Activity#RESULT_OK} and set
   2330              *  the following in the result extra values:</p>
   2331              *
   2332              * <ul>
   2333              *   <li><em>"messageref"</em> - (int) The new message reference number which will be
   2334              *   later used in the updateMmsDownloadStatus call.</li>
   2335              * </ul>
   2336              *
   2337              * <p>If a BroadcastReceiver cannot download the message, it should not set the result
   2338              *  code and the platform will download it via the normal pathway.
   2339              * </p>
   2340              *
   2341              * <p class="note"><strong>Note:</strong>
   2342              * The broadcast receiver that filters for this intent must be a carrier privileged app.
   2343              * It must also declare {@link android.Manifest.permission#BROADCAST_WAP_PUSH} as a required
   2344              * permission in the <a href="{@docRoot}guide/topics/manifest/receiver-element.html">
   2345              * {@code &lt;receiver>}</a> tag.
   2346              * {@hide}
   2347              */
   2348             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   2349             public static final String MMS_DOWNLOAD_ACTION =
   2350                     "android.provider.Telephony.MMS_DOWNLOAD";
   2351 
   2352             /**
   2353              * An extra field which stores the URI of deleted contents.
   2354              */
   2355             public static final String DELETED_CONTENTS = "deleted_contents";
   2356 
   2357             /**
   2358              * The content provider of the PDU to be sent/downloaded passed as an extra for
   2359              * {@link #MMS_DOWNLOAD_ACTION} and {@link #MMS_SEND_ACTION}.
   2360              * {@hide}
   2361              */
   2362             public static final String EXTRA_MMS_CONTENT_URI =
   2363                     "android.provider.Telephony.extra.MMS_CONTENT_URI";
   2364 
   2365             /**
   2366              * The message URL to be downloaded passed as an extra for {@link #MMS_DOWNLOAD_ACTION}.
   2367              * It is also the URL to send an MMS to passed as an extra for
   2368              * {@link #MMS_SEND_ACTION}.
   2369              * {@hide}
   2370              */
   2371             public static final String EXTRA_MMS_LOCATION_URL =
   2372                     "android.provider.Telephony.extra.MMS_LOCATION_URL";
   2373         }
   2374     }
   2375 
   2376     /**
   2377      * Contains all MMS and SMS messages.
   2378      */
   2379     public static final class MmsSms implements BaseColumns {
   2380 
   2381         /**
   2382          * Not instantiable.
   2383          * @hide
   2384          */
   2385         private MmsSms() {
   2386         }
   2387 
   2388         /**
   2389          * The column to distinguish SMS and MMS messages in query results.
   2390          */
   2391         public static final String TYPE_DISCRIMINATOR_COLUMN =
   2392                 "transport_type";
   2393 
   2394         /**
   2395          * The {@code content://} style URL for this table.
   2396          */
   2397         public static final Uri CONTENT_URI = Uri.parse("content://mms-sms/");
   2398 
   2399         /**
   2400          * The {@code content://} style URL for this table, by conversation.
   2401          */
   2402         public static final Uri CONTENT_CONVERSATIONS_URI = Uri.parse(
   2403                 "content://mms-sms/conversations");
   2404 
   2405         /**
   2406          * The {@code content://} style URL for this table, by phone number.
   2407          */
   2408         public static final Uri CONTENT_FILTER_BYPHONE_URI = Uri.parse(
   2409                 "content://mms-sms/messages/byphone");
   2410 
   2411         /**
   2412          * The {@code content://} style URL for undelivered messages in this table.
   2413          */
   2414         public static final Uri CONTENT_UNDELIVERED_URI = Uri.parse(
   2415                 "content://mms-sms/undelivered");
   2416 
   2417         /**
   2418          * The {@code content://} style URL for draft messages in this table.
   2419          */
   2420         public static final Uri CONTENT_DRAFT_URI = Uri.parse(
   2421                 "content://mms-sms/draft");
   2422 
   2423         /**
   2424          * The {@code content://} style URL for locked messages in this table.
   2425          */
   2426         public static final Uri CONTENT_LOCKED_URI = Uri.parse(
   2427                 "content://mms-sms/locked");
   2428 
   2429         /**
   2430          * Pass in a query parameter called "pattern" which is the text to search for.
   2431          * The sort order is fixed to be: {@code thread_id ASC, date DESC}.
   2432          */
   2433         public static final Uri SEARCH_URI = Uri.parse(
   2434                 "content://mms-sms/search");
   2435 
   2436         // Constants for message protocol types.
   2437 
   2438         /** SMS protocol type. */
   2439         public static final int SMS_PROTO = 0;
   2440 
   2441         /** MMS protocol type. */
   2442         public static final int MMS_PROTO = 1;
   2443 
   2444         // Constants for error types of pending messages.
   2445 
   2446         /** Error type: no error. */
   2447         public static final int NO_ERROR                      = 0;
   2448 
   2449         /** Error type: generic transient error. */
   2450         public static final int ERR_TYPE_GENERIC              = 1;
   2451 
   2452         /** Error type: SMS protocol transient error. */
   2453         public static final int ERR_TYPE_SMS_PROTO_TRANSIENT  = 2;
   2454 
   2455         /** Error type: MMS protocol transient error. */
   2456         public static final int ERR_TYPE_MMS_PROTO_TRANSIENT  = 3;
   2457 
   2458         /** Error type: transport failure. */
   2459         public static final int ERR_TYPE_TRANSPORT_FAILURE    = 4;
   2460 
   2461         /** Error type: permanent error (along with all higher error values). */
   2462         public static final int ERR_TYPE_GENERIC_PERMANENT    = 10;
   2463 
   2464         /** Error type: SMS protocol permanent error. */
   2465         public static final int ERR_TYPE_SMS_PROTO_PERMANENT  = 11;
   2466 
   2467         /** Error type: MMS protocol permanent error. */
   2468         public static final int ERR_TYPE_MMS_PROTO_PERMANENT  = 12;
   2469 
   2470         /**
   2471          * Contains pending messages info.
   2472          */
   2473         public static final class PendingMessages implements BaseColumns {
   2474 
   2475             /**
   2476              * Not instantiable.
   2477              * @hide
   2478              */
   2479             private PendingMessages() {
   2480             }
   2481 
   2482             public static final Uri CONTENT_URI = Uri.withAppendedPath(
   2483                     MmsSms.CONTENT_URI, "pending");
   2484 
   2485             /**
   2486              * The type of transport protocol (MMS or SMS).
   2487              * <P>Type: INTEGER</P>
   2488              */
   2489             public static final String PROTO_TYPE = "proto_type";
   2490 
   2491             /**
   2492              * The ID of the message to be sent or downloaded.
   2493              * <P>Type: INTEGER (long)</P>
   2494              */
   2495             public static final String MSG_ID = "msg_id";
   2496 
   2497             /**
   2498              * The type of the message to be sent or downloaded.
   2499              * This field is only valid for MM. For SM, its value is always set to 0.
   2500              * <P>Type: INTEGER</P>
   2501              */
   2502             public static final String MSG_TYPE = "msg_type";
   2503 
   2504             /**
   2505              * The type of the error code.
   2506              * <P>Type: INTEGER</P>
   2507              */
   2508             public static final String ERROR_TYPE = "err_type";
   2509 
   2510             /**
   2511              * The error code of sending/retrieving process.
   2512              * <P>Type: INTEGER</P>
   2513              */
   2514             public static final String ERROR_CODE = "err_code";
   2515 
   2516             /**
   2517              * How many times we tried to send or download the message.
   2518              * <P>Type: INTEGER</P>
   2519              */
   2520             public static final String RETRY_INDEX = "retry_index";
   2521 
   2522             /**
   2523              * The time to do next retry.
   2524              * <P>Type: INTEGER (long)</P>
   2525              */
   2526             public static final String DUE_TIME = "due_time";
   2527 
   2528             /**
   2529              * The time we last tried to send or download the message.
   2530              * <P>Type: INTEGER (long)</P>
   2531              */
   2532             public static final String LAST_TRY = "last_try";
   2533 
   2534             /**
   2535              * The sub_id to which the pending message belongs to
   2536              * <p>Type: INTEGER (long) </p>
   2537              * @hide
   2538              */
   2539             public static final String SUB_ID = "pending_sub_id";
   2540         }
   2541 
   2542         /**
   2543          * Words table used by provider for full-text searches.
   2544          * @hide
   2545          */
   2546         public static final class WordsTable {
   2547 
   2548             /**
   2549              * Not instantiable.
   2550              * @hide
   2551              */
   2552             private WordsTable() {}
   2553 
   2554             /**
   2555              * Primary key.
   2556              * <P>Type: INTEGER (long)</P>
   2557              */
   2558             public static final String ID = "_id";
   2559 
   2560             /**
   2561              * Source row ID.
   2562              * <P>Type: INTEGER (long)</P>
   2563              */
   2564             public static final String SOURCE_ROW_ID = "source_id";
   2565 
   2566             /**
   2567              * Table ID (either 1 or 2).
   2568              * <P>Type: INTEGER</P>
   2569              */
   2570             public static final String TABLE_ID = "table_to_use";
   2571 
   2572             /**
   2573              * The words to index.
   2574              * <P>Type: TEXT</P>
   2575              */
   2576             public static final String INDEXED_TEXT = "index_text";
   2577         }
   2578     }
   2579 
   2580     /**
   2581      * Carriers class contains information about APNs, including MMSC information.
   2582      */
   2583     public static final class Carriers implements BaseColumns {
   2584 
   2585         /**
   2586          * Not instantiable.
   2587          * @hide
   2588          */
   2589         private Carriers() {}
   2590 
   2591         /**
   2592          * The {@code content://} style URL for this table.
   2593          */
   2594         public static final Uri CONTENT_URI = Uri.parse("content://telephony/carriers");
   2595 
   2596         /**
   2597          * The default sort order for this table.
   2598          */
   2599         public static final String DEFAULT_SORT_ORDER = "name ASC";
   2600 
   2601         /**
   2602          * Entry name.
   2603          * <P>Type: TEXT</P>
   2604          */
   2605         public static final String NAME = "name";
   2606 
   2607         /**
   2608          * APN name.
   2609          * <P>Type: TEXT</P>
   2610          */
   2611         public static final String APN = "apn";
   2612 
   2613         /**
   2614          * Proxy address.
   2615          * <P>Type: TEXT</P>
   2616          */
   2617         public static final String PROXY = "proxy";
   2618 
   2619         /**
   2620          * Proxy port.
   2621          * <P>Type: TEXT</P>
   2622          */
   2623         public static final String PORT = "port";
   2624 
   2625         /**
   2626          * MMS proxy address.
   2627          * <P>Type: TEXT</P>
   2628          */
   2629         public static final String MMSPROXY = "mmsproxy";
   2630 
   2631         /**
   2632          * MMS proxy port.
   2633          * <P>Type: TEXT</P>
   2634          */
   2635         public static final String MMSPORT = "mmsport";
   2636 
   2637         /**
   2638          * Server address.
   2639          * <P>Type: TEXT</P>
   2640          */
   2641         public static final String SERVER = "server";
   2642 
   2643         /**
   2644          * APN username.
   2645          * <P>Type: TEXT</P>
   2646          */
   2647         public static final String USER = "user";
   2648 
   2649         /**
   2650          * APN password.
   2651          * <P>Type: TEXT</P>
   2652          */
   2653         public static final String PASSWORD = "password";
   2654 
   2655         /**
   2656          * MMSC URL.
   2657          * <P>Type: TEXT</P>
   2658          */
   2659         public static final String MMSC = "mmsc";
   2660 
   2661         /**
   2662          * Mobile Country Code (MCC).
   2663          * <P>Type: TEXT</P>
   2664          */
   2665         public static final String MCC = "mcc";
   2666 
   2667         /**
   2668          * Mobile Network Code (MNC).
   2669          * <P>Type: TEXT</P>
   2670          */
   2671         public static final String MNC = "mnc";
   2672 
   2673         /**
   2674          * Numeric operator ID (as String). Usually {@code MCC + MNC}.
   2675          * <P>Type: TEXT</P>
   2676          */
   2677         public static final String NUMERIC = "numeric";
   2678 
   2679         /**
   2680          * Authentication type.
   2681          * <P>Type:  INTEGER</P>
   2682          */
   2683         public static final String AUTH_TYPE = "authtype";
   2684 
   2685         /**
   2686          * Comma-delimited list of APN types.
   2687          * <P>Type: TEXT</P>
   2688          */
   2689         public static final String TYPE = "type";
   2690 
   2691         /**
   2692          * The protocol to use to connect to this APN.
   2693          *
   2694          * One of the {@code PDP_type} values in TS 27.007 section 10.1.1.
   2695          * For example: {@code IP}, {@code IPV6}, {@code IPV4V6}, or {@code PPP}.
   2696          * <P>Type: TEXT</P>
   2697          */
   2698         public static final String PROTOCOL = "protocol";
   2699 
   2700         /**
   2701          * The protocol to use to connect to this APN when roaming.
   2702          * The syntax is the same as protocol.
   2703          * <P>Type: TEXT</P>
   2704          */
   2705         public static final String ROAMING_PROTOCOL = "roaming_protocol";
   2706 
   2707         /**
   2708          * Is this the current APN?
   2709          * <P>Type: INTEGER (boolean)</P>
   2710          */
   2711         public static final String CURRENT = "current";
   2712 
   2713         /**
   2714          * Is this APN enabled?
   2715          * <P>Type: INTEGER (boolean)</P>
   2716          */
   2717         public static final String CARRIER_ENABLED = "carrier_enabled";
   2718 
   2719         /**
   2720          * Radio Access Technology info.
   2721          * To check what values are allowed, refer to {@link android.telephony.ServiceState}.
   2722          * This should be spread to other technologies,
   2723          * but is currently only used for LTE (14) and eHRPD (13).
   2724          * <P>Type: INTEGER</P>
   2725          */
   2726         public static final String BEARER = "bearer";
   2727 
   2728         /**
   2729          * MVNO type:
   2730          * {@code SPN (Service Provider Name), IMSI, GID (Group Identifier Level 1)}.
   2731          * <P>Type: TEXT</P>
   2732          */
   2733         public static final String MVNO_TYPE = "mvno_type";
   2734 
   2735         /**
   2736          * MVNO data.
   2737          * Use the following examples.
   2738          * <ul>
   2739          *     <li>SPN: A MOBILE, BEN NL, ...</li>
   2740          *     <li>IMSI: 302720x94, 2060188, ...</li>
   2741          *     <li>GID: 4E, 33, ...</li>
   2742          * </ul>
   2743          * <P>Type: TEXT</P>
   2744          */
   2745         public static final String MVNO_MATCH_DATA = "mvno_match_data";
   2746 
   2747         /**
   2748          * The sub_id to which the APN belongs to
   2749          * <p>Type: INTEGER (long) </p>
   2750          * @hide
   2751          */
   2752         public static final String SUB_ID = "sub_id";
   2753 
   2754         /**
   2755          * The profile_id to which the APN saved in modem
   2756          * <p>Type: INTEGER</p>
   2757          *@hide
   2758          */
   2759         public static final String PROFILE_ID = "profile_id";
   2760 
   2761         /**
   2762          * Is the apn setting to be set in modem
   2763          * <P>Type: INTEGER (boolean)</P>
   2764          *@hide
   2765          */
   2766         public static final String MODEM_COGNITIVE = "modem_cognitive";
   2767 
   2768         /**
   2769          * The max connections of this apn
   2770          * <p>Type: INTEGER</p>
   2771          *@hide
   2772          */
   2773         public static final String MAX_CONNS = "max_conns";
   2774 
   2775         /**
   2776          * The wait time for retry of the apn
   2777          * <p>Type: INTEGER</p>
   2778          *@hide
   2779          */
   2780         public static final String WAIT_TIME = "wait_time";
   2781 
   2782         /**
   2783          * The time to limit max connection for the apn
   2784          * <p>Type: INTEGER</p>
   2785          *@hide
   2786          */
   2787         public static final String MAX_CONNS_TIME = "max_conns_time";
   2788 
   2789         /**
   2790          * The MTU size of the mobile interface to  which the APN connected
   2791          * <p>Type: INTEGER </p>
   2792          * @hide
   2793          */
   2794         public static final String MTU = "mtu";
   2795     }
   2796 
   2797     /**
   2798      * Contains received SMS cell broadcast messages.
   2799      * @hide
   2800      */
   2801     public static final class CellBroadcasts implements BaseColumns {
   2802 
   2803         /**
   2804          * Not instantiable.
   2805          * @hide
   2806          */
   2807         private CellBroadcasts() {}
   2808 
   2809         /**
   2810          * The {@code content://} URI for this table.
   2811          */
   2812         public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts");
   2813 
   2814         /**
   2815          * Message geographical scope.
   2816          * <P>Type: INTEGER</P>
   2817          */
   2818         public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
   2819 
   2820         /**
   2821          * Message serial number.
   2822          * <P>Type: INTEGER</P>
   2823          */
   2824         public static final String SERIAL_NUMBER = "serial_number";
   2825 
   2826         /**
   2827          * PLMN of broadcast sender. {@code SERIAL_NUMBER + PLMN + LAC + CID} uniquely identifies
   2828          * a broadcast for duplicate detection purposes.
   2829          * <P>Type: TEXT</P>
   2830          */
   2831         public static final String PLMN = "plmn";
   2832 
   2833         /**
   2834          * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA.
   2835          * Only included if Geographical Scope of message is not PLMN wide (01).
   2836          * <P>Type: INTEGER</P>
   2837          */
   2838         public static final String LAC = "lac";
   2839 
   2840         /**
   2841          * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the
   2842          * Geographical Scope of message is cell wide (00 or 11).
   2843          * <P>Type: INTEGER</P>
   2844          */
   2845         public static final String CID = "cid";
   2846 
   2847         /**
   2848          * Message code. <em>OBSOLETE: merged into SERIAL_NUMBER.</em>
   2849          * <P>Type: INTEGER</P>
   2850          */
   2851         public static final String V1_MESSAGE_CODE = "message_code";
   2852 
   2853         /**
   2854          * Message identifier. <em>OBSOLETE: renamed to SERVICE_CATEGORY.</em>
   2855          * <P>Type: INTEGER</P>
   2856          */
   2857         public static final String V1_MESSAGE_IDENTIFIER = "message_id";
   2858 
   2859         /**
   2860          * Service category (GSM/UMTS: message identifier; CDMA: service category).
   2861          * <P>Type: INTEGER</P>
   2862          */
   2863         public static final String SERVICE_CATEGORY = "service_category";
   2864 
   2865         /**
   2866          * Message language code.
   2867          * <P>Type: TEXT</P>
   2868          */
   2869         public static final String LANGUAGE_CODE = "language";
   2870 
   2871         /**
   2872          * Message body.
   2873          * <P>Type: TEXT</P>
   2874          */
   2875         public static final String MESSAGE_BODY = "body";
   2876 
   2877         /**
   2878          * Message delivery time.
   2879          * <P>Type: INTEGER (long)</P>
   2880          */
   2881         public static final String DELIVERY_TIME = "date";
   2882 
   2883         /**
   2884          * Has the message been viewed?
   2885          * <P>Type: INTEGER (boolean)</P>
   2886          */
   2887         public static final String MESSAGE_READ = "read";
   2888 
   2889         /**
   2890          * Message format (3GPP or 3GPP2).
   2891          * <P>Type: INTEGER</P>
   2892          */
   2893         public static final String MESSAGE_FORMAT = "format";
   2894 
   2895         /**
   2896          * Message priority (including emergency).
   2897          * <P>Type: INTEGER</P>
   2898          */
   2899         public static final String MESSAGE_PRIORITY = "priority";
   2900 
   2901         /**
   2902          * ETWS warning type (ETWS alerts only).
   2903          * <P>Type: INTEGER</P>
   2904          */
   2905         public static final String ETWS_WARNING_TYPE = "etws_warning_type";
   2906 
   2907         /**
   2908          * CMAS message class (CMAS alerts only).
   2909          * <P>Type: INTEGER</P>
   2910          */
   2911         public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
   2912 
   2913         /**
   2914          * CMAS category (CMAS alerts only).
   2915          * <P>Type: INTEGER</P>
   2916          */
   2917         public static final String CMAS_CATEGORY = "cmas_category";
   2918 
   2919         /**
   2920          * CMAS response type (CMAS alerts only).
   2921          * <P>Type: INTEGER</P>
   2922          */
   2923         public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
   2924 
   2925         /**
   2926          * CMAS severity (CMAS alerts only).
   2927          * <P>Type: INTEGER</P>
   2928          */
   2929         public static final String CMAS_SEVERITY = "cmas_severity";
   2930 
   2931         /**
   2932          * CMAS urgency (CMAS alerts only).
   2933          * <P>Type: INTEGER</P>
   2934          */
   2935         public static final String CMAS_URGENCY = "cmas_urgency";
   2936 
   2937         /**
   2938          * CMAS certainty (CMAS alerts only).
   2939          * <P>Type: INTEGER</P>
   2940          */
   2941         public static final String CMAS_CERTAINTY = "cmas_certainty";
   2942 
   2943         /** The default sort order for this table. */
   2944         public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
   2945 
   2946         /**
   2947          * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
   2948          */
   2949         public static final String[] QUERY_COLUMNS = {
   2950                 _ID,
   2951                 GEOGRAPHICAL_SCOPE,
   2952                 PLMN,
   2953                 LAC,
   2954                 CID,
   2955                 SERIAL_NUMBER,
   2956                 SERVICE_CATEGORY,
   2957                 LANGUAGE_CODE,
   2958                 MESSAGE_BODY,
   2959                 DELIVERY_TIME,
   2960                 MESSAGE_READ,
   2961                 MESSAGE_FORMAT,
   2962                 MESSAGE_PRIORITY,
   2963                 ETWS_WARNING_TYPE,
   2964                 CMAS_MESSAGE_CLASS,
   2965                 CMAS_CATEGORY,
   2966                 CMAS_RESPONSE_TYPE,
   2967                 CMAS_SEVERITY,
   2968                 CMAS_URGENCY,
   2969                 CMAS_CERTAINTY
   2970         };
   2971     }
   2972 }
   2973