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