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