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