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