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