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