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