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