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