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