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