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