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