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              * Broadcast Action: A new Emergency Broadcast message has been received
992              * by the device. The intent will have the following extra
993              * values:</p>
994              *
995              * <ul>
996              *   <li><em>"message"</em> - An SmsCbMessage object containing the broadcast message
997              *   data, including ETWS or CMAS warning notification info if present.</li>
998              * </ul>
999              *
1000              * <p>The extra values can be extracted using
1001              * {@link #getMessagesFromIntent(Intent)}.</p>
1002              *
1003              * <p>If a BroadcastReceiver encounters an error while processing
1004              * this intent it should set the result code appropriately.</p>
1005              */
1006             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1007             public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
1008                     "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
1009 
1010             /**
1011              * Broadcast Action: A new CDMA SMS has been received containing Service Category
1012              * Program Data (updates the list of enabled broadcast channels). The intent will
1013              * have the following extra values:</p>
1014              *
1015              * <ul>
1016              *   <li><em>"operations"</em> - An array of CdmaSmsCbProgramData objects containing
1017              *   the service category operations (add/delete/clear) to perform.</li>
1018              * </ul>
1019              *
1020              * <p>The extra values can be extracted using
1021              * {@link #getMessagesFromIntent(Intent)}.</p>
1022              *
1023              * <p>If a BroadcastReceiver encounters an error while processing
1024              * this intent it should set the result code appropriately.</p>
1025              */
1026             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1027             public static final String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION =
1028                     "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
1029 
1030             /**
1031              * Broadcast Action: The SIM storage for SMS messages is full.  If
1032              * space is not freed, messages targeted for the SIM (class 2) may
1033              * not be saved.
1034              */
1035             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1036             public static final String SIM_FULL_ACTION =
1037                     "android.provider.Telephony.SIM_FULL";
1038 
1039             /**
1040              * Broadcast Action: An incoming SMS has been rejected by the
1041              * telephony framework.  This intent is sent in lieu of any
1042              * of the RECEIVED_ACTION intents.  The intent will have the
1043              * following extra value:</p>
1044              *
1045              * <ul>
1046              *   <li><em>"result"</em> - An int result code, e.g. {@link #RESULT_SMS_OUT_OF_MEMORY}
1047              *   indicating the error returned to the network.</li>
1048              * </ul>
1049              */
1050             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1051             public static final String SMS_REJECTED_ACTION =
1052                 "android.provider.Telephony.SMS_REJECTED";
1053 
1054             /**
1055              * Broadcast Action: An incoming MMS has been downloaded. The intent is sent to all
1056              * users, except for secondary users where SMS has been disabled and to managed
1057              * profiles.
1058              * @hide
1059              */
1060             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1061             public static final String MMS_DOWNLOADED_ACTION =
1062                 "android.provider.Telephony.MMS_DOWNLOADED";
1063 
1064             /**
1065              * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
1066              * {@link #DATA_SMS_RECEIVED_ACTION} intent.
1067              *
1068              * @param intent the intent to read from
1069              * @return an array of SmsMessages for the PDUs
1070              */
getMessagesFromIntent(Intent intent)1071             public static SmsMessage[] getMessagesFromIntent(Intent intent) {
1072                 Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
1073                 String format = intent.getStringExtra("format");
1074                 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1075                         SubscriptionManager.getDefaultSmsSubId());
1076 
1077                 Rlog.v(TAG, " getMessagesFromIntent sub_id : " + subId);
1078 
1079                 int pduCount = messages.length;
1080                 SmsMessage[] msgs = new SmsMessage[pduCount];
1081 
1082                 for (int i = 0; i < pduCount; i++) {
1083                     byte[] pdu = (byte[]) messages[i];
1084                     msgs[i] = SmsMessage.createFromPdu(pdu, format);
1085                     msgs[i].setSubId(subId);
1086                 }
1087                 return msgs;
1088             }
1089         }
1090     }
1091 
1092     /**
1093      * Base columns for tables that contain MMSs.
1094      */
1095     public interface BaseMmsColumns extends BaseColumns {
1096 
1097         /** Message box: all messages. */
1098         public static final int MESSAGE_BOX_ALL    = 0;
1099         /** Message box: inbox. */
1100         public static final int MESSAGE_BOX_INBOX  = 1;
1101         /** Message box: sent messages. */
1102         public static final int MESSAGE_BOX_SENT   = 2;
1103         /** Message box: drafts. */
1104         public static final int MESSAGE_BOX_DRAFTS = 3;
1105         /** Message box: outbox. */
1106         public static final int MESSAGE_BOX_OUTBOX = 4;
1107         /** Message box: failed. */
1108         public static final int MESSAGE_BOX_FAILED = 5;
1109 
1110         /**
1111          * The thread ID of the message.
1112          * <P>Type: INTEGER (long)</P>
1113          */
1114         public static final String THREAD_ID = "thread_id";
1115 
1116         /**
1117          * The date the message was received.
1118          * <P>Type: INTEGER (long)</P>
1119          */
1120         public static final String DATE = "date";
1121 
1122         /**
1123          * The date the message was sent.
1124          * <P>Type: INTEGER (long)</P>
1125          */
1126         public static final String DATE_SENT = "date_sent";
1127 
1128         /**
1129          * The box which the message belongs to, e.g. {@link #MESSAGE_BOX_INBOX}.
1130          * <P>Type: INTEGER</P>
1131          */
1132         public static final String MESSAGE_BOX = "msg_box";
1133 
1134         /**
1135          * Has the message been read?
1136          * <P>Type: INTEGER (boolean)</P>
1137          */
1138         public static final String READ = "read";
1139 
1140         /**
1141          * Has the message been seen by the user? The "seen" flag determines
1142          * whether we need to show a new message notification.
1143          * <P>Type: INTEGER (boolean)</P>
1144          */
1145         public static final String SEEN = "seen";
1146 
1147         /**
1148          * Does the message have only a text part (can also have a subject) with
1149          * no picture, slideshow, sound, etc. parts?
1150          * <P>Type: INTEGER (boolean)</P>
1151          */
1152         public static final String TEXT_ONLY = "text_only";
1153 
1154         /**
1155          * The {@code Message-ID} of the message.
1156          * <P>Type: TEXT</P>
1157          */
1158         public static final String MESSAGE_ID = "m_id";
1159 
1160         /**
1161          * The subject of the message, if present.
1162          * <P>Type: TEXT</P>
1163          */
1164         public static final String SUBJECT = "sub";
1165 
1166         /**
1167          * The character set of the subject, if present.
1168          * <P>Type: INTEGER</P>
1169          */
1170         public static final String SUBJECT_CHARSET = "sub_cs";
1171 
1172         /**
1173          * The {@code Content-Type} of the message.
1174          * <P>Type: TEXT</P>
1175          */
1176         public static final String CONTENT_TYPE = "ct_t";
1177 
1178         /**
1179          * The {@code Content-Location} of the message.
1180          * <P>Type: TEXT</P>
1181          */
1182         public static final String CONTENT_LOCATION = "ct_l";
1183 
1184         /**
1185          * The expiry time of the message.
1186          * <P>Type: INTEGER (long)</P>
1187          */
1188         public static final String EXPIRY = "exp";
1189 
1190         /**
1191          * The class of the message.
1192          * <P>Type: TEXT</P>
1193          */
1194         public static final String MESSAGE_CLASS = "m_cls";
1195 
1196         /**
1197          * The type of the message defined by MMS spec.
1198          * <P>Type: INTEGER</P>
1199          */
1200         public static final String MESSAGE_TYPE = "m_type";
1201 
1202         /**
1203          * The version of the specification that this message conforms to.
1204          * <P>Type: INTEGER</P>
1205          */
1206         public static final String MMS_VERSION = "v";
1207 
1208         /**
1209          * The size of the message.
1210          * <P>Type: INTEGER</P>
1211          */
1212         public static final String MESSAGE_SIZE = "m_size";
1213 
1214         /**
1215          * The priority of the message.
1216          * <P>Type: INTEGER</P>
1217          */
1218         public static final String PRIORITY = "pri";
1219 
1220         /**
1221          * The {@code read-report} of the message.
1222          * <P>Type: INTEGER (boolean)</P>
1223          */
1224         public static final String READ_REPORT = "rr";
1225 
1226         /**
1227          * Is read report allowed?
1228          * <P>Type: INTEGER (boolean)</P>
1229          */
1230         public static final String REPORT_ALLOWED = "rpt_a";
1231 
1232         /**
1233          * The {@code response-status} of the message.
1234          * <P>Type: INTEGER</P>
1235          */
1236         public static final String RESPONSE_STATUS = "resp_st";
1237 
1238         /**
1239          * The {@code status} of the message.
1240          * <P>Type: INTEGER</P>
1241          */
1242         public static final String STATUS = "st";
1243 
1244         /**
1245          * The {@code transaction-id} of the message.
1246          * <P>Type: TEXT</P>
1247          */
1248         public static final String TRANSACTION_ID = "tr_id";
1249 
1250         /**
1251          * The {@code retrieve-status} of the message.
1252          * <P>Type: INTEGER</P>
1253          */
1254         public static final String RETRIEVE_STATUS = "retr_st";
1255 
1256         /**
1257          * The {@code retrieve-text} of the message.
1258          * <P>Type: TEXT</P>
1259          */
1260         public static final String RETRIEVE_TEXT = "retr_txt";
1261 
1262         /**
1263          * The character set of the retrieve-text.
1264          * <P>Type: INTEGER</P>
1265          */
1266         public static final String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
1267 
1268         /**
1269          * The {@code read-status} of the message.
1270          * <P>Type: INTEGER</P>
1271          */
1272         public static final String READ_STATUS = "read_status";
1273 
1274         /**
1275          * The {@code content-class} of the message.
1276          * <P>Type: INTEGER</P>
1277          */
1278         public static final String CONTENT_CLASS = "ct_cls";
1279 
1280         /**
1281          * The {@code delivery-report} of the message.
1282          * <P>Type: INTEGER</P>
1283          */
1284         public static final String DELIVERY_REPORT = "d_rpt";
1285 
1286         /**
1287          * The {@code delivery-time-token} of the message.
1288          * <P>Type: INTEGER</P>
1289          * @deprecated this column is no longer supported.
1290          * @hide
1291          */
1292         @Deprecated
1293         public static final String DELIVERY_TIME_TOKEN = "d_tm_tok";
1294 
1295         /**
1296          * The {@code delivery-time} of the message.
1297          * <P>Type: INTEGER</P>
1298          */
1299         public static final String DELIVERY_TIME = "d_tm";
1300 
1301         /**
1302          * The {@code response-text} of the message.
1303          * <P>Type: TEXT</P>
1304          */
1305         public static final String RESPONSE_TEXT = "resp_txt";
1306 
1307         /**
1308          * The {@code sender-visibility} of the message.
1309          * <P>Type: TEXT</P>
1310          * @deprecated this column is no longer supported.
1311          * @hide
1312          */
1313         @Deprecated
1314         public static final String SENDER_VISIBILITY = "s_vis";
1315 
1316         /**
1317          * The {@code reply-charging} of the message.
1318          * <P>Type: INTEGER</P>
1319          * @deprecated this column is no longer supported.
1320          * @hide
1321          */
1322         @Deprecated
1323         public static final String REPLY_CHARGING = "r_chg";
1324 
1325         /**
1326          * The {@code reply-charging-deadline-token} 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_DEADLINE_TOKEN = "r_chg_dl_tok";
1333 
1334         /**
1335          * The {@code reply-charging-deadline} 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 = "r_chg_dl";
1342 
1343         /**
1344          * The {@code reply-charging-id} of the message.
1345          * <P>Type: TEXT</P>
1346          * @deprecated this column is no longer supported.
1347          * @hide
1348          */
1349         @Deprecated
1350         public static final String REPLY_CHARGING_ID = "r_chg_id";
1351 
1352         /**
1353          * The {@code reply-charging-size} of the message.
1354          * <P>Type: INTEGER</P>
1355          * @deprecated this column is no longer supported.
1356          * @hide
1357          */
1358         @Deprecated
1359         public static final String REPLY_CHARGING_SIZE = "r_chg_sz";
1360 
1361         /**
1362          * The {@code previously-sent-by} of the message.
1363          * <P>Type: TEXT</P>
1364          * @deprecated this column is no longer supported.
1365          * @hide
1366          */
1367         @Deprecated
1368         public static final String PREVIOUSLY_SENT_BY = "p_s_by";
1369 
1370         /**
1371          * The {@code previously-sent-date} of the message.
1372          * <P>Type: INTEGER</P>
1373          * @deprecated this column is no longer supported.
1374          * @hide
1375          */
1376         @Deprecated
1377         public static final String PREVIOUSLY_SENT_DATE = "p_s_d";
1378 
1379         /**
1380          * The {@code store} of the message.
1381          * <P>Type: TEXT</P>
1382          * @deprecated this column is no longer supported.
1383          * @hide
1384          */
1385         @Deprecated
1386         public static final String STORE = "store";
1387 
1388         /**
1389          * The {@code mm-state} of the message.
1390          * <P>Type: INTEGER</P>
1391          * @deprecated this column is no longer supported.
1392          * @hide
1393          */
1394         @Deprecated
1395         public static final String MM_STATE = "mm_st";
1396 
1397         /**
1398          * The {@code mm-flags-token} 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_FLAGS_TOKEN = "mm_flg_tok";
1405 
1406         /**
1407          * The {@code mm-flags} of the message.
1408          * <P>Type: TEXT</P>
1409          * @deprecated this column is no longer supported.
1410          * @hide
1411          */
1412         @Deprecated
1413         public static final String MM_FLAGS = "mm_flg";
1414 
1415         /**
1416          * The {@code store-status} 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 STORE_STATUS = "store_st";
1423 
1424         /**
1425          * The {@code store-status-text} 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_TEXT = "store_st_txt";
1432 
1433         /**
1434          * The {@code stored} 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 STORED = "stored";
1441 
1442         /**
1443          * The {@code totals} 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 TOTALS = "totals";
1450 
1451         /**
1452          * The {@code mbox-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 MBOX_TOTALS = "mb_t";
1459 
1460         /**
1461          * The {@code mbox-totals-token} of the message.
1462          * <P>Type: INTEGER</P>
1463          * @deprecated this column is no longer supported.
1464          * @hide
1465          */
1466         @Deprecated
1467         public static final String MBOX_TOTALS_TOKEN = "mb_t_tok";
1468 
1469         /**
1470          * The {@code quotas} of the message.
1471          * <P>Type: TEXT</P>
1472          * @deprecated this column is no longer supported.
1473          * @hide
1474          */
1475         @Deprecated
1476         public static final String QUOTAS = "qt";
1477 
1478         /**
1479          * The {@code mbox-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 MBOX_QUOTAS = "mb_qt";
1486 
1487         /**
1488          * The {@code mbox-quotas-token} of the message.
1489          * <P>Type: INTEGER</P>
1490          * @deprecated this column is no longer supported.
1491          * @hide
1492          */
1493         @Deprecated
1494         public static final String MBOX_QUOTAS_TOKEN = "mb_qt_tok";
1495 
1496         /**
1497          * The {@code message-count} 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 MESSAGE_COUNT = "m_cnt";
1504 
1505         /**
1506          * The {@code start} 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 START = "start";
1513 
1514         /**
1515          * The {@code distribution-indicator} of the message.
1516          * <P>Type: TEXT</P>
1517          * @deprecated this column is no longer supported.
1518          * @hide
1519          */
1520         @Deprecated
1521         public static final String DISTRIBUTION_INDICATOR = "d_ind";
1522 
1523         /**
1524          * The {@code element-descriptor} 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 ELEMENT_DESCRIPTOR = "e_des";
1531 
1532         /**
1533          * The {@code limit} of the message.
1534          * <P>Type: INTEGER</P>
1535          * @deprecated this column is no longer supported.
1536          * @hide
1537          */
1538         @Deprecated
1539         public static final String LIMIT = "limit";
1540 
1541         /**
1542          * The {@code recommended-retrieval-mode} 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 RECOMMENDED_RETRIEVAL_MODE = "r_r_mod";
1549 
1550         /**
1551          * The {@code recommended-retrieval-mode-text} of the message.
1552          * <P>Type: TEXT</P>
1553          * @deprecated this column is no longer supported.
1554          * @hide
1555          */
1556         @Deprecated
1557         public static final String RECOMMENDED_RETRIEVAL_MODE_TEXT = "r_r_mod_txt";
1558 
1559         /**
1560          * The {@code status-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 STATUS_TEXT = "st_txt";
1567 
1568         /**
1569          * The {@code applic-id} 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 APPLIC_ID = "apl_id";
1576 
1577         /**
1578          * The {@code reply-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 REPLY_APPLIC_ID = "r_apl_id";
1585 
1586         /**
1587          * The {@code aux-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 AUX_APPLIC_ID = "aux_apl_id";
1594 
1595         /**
1596          * The {@code drm-content} 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 DRM_CONTENT = "drm_c";
1603 
1604         /**
1605          * The {@code adaptation-allowed} 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 ADAPTATION_ALLOWED = "adp_a";
1612 
1613         /**
1614          * The {@code replace-id} of the message.
1615          * <P>Type: TEXT</P>
1616          * @deprecated this column is no longer supported.
1617          * @hide
1618          */
1619         @Deprecated
1620         public static final String REPLACE_ID = "repl_id";
1621 
1622         /**
1623          * The {@code cancel-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 CANCEL_ID = "cl_id";
1630 
1631         /**
1632          * The {@code cancel-status} of the message.
1633          * <P>Type: INTEGER</P>
1634          * @deprecated this column is no longer supported.
1635          * @hide
1636          */
1637         @Deprecated
1638         public static final String CANCEL_STATUS = "cl_st";
1639 
1640         /**
1641          * Is the message locked?
1642          * <P>Type: INTEGER (boolean)</P>
1643          */
1644         public static final String LOCKED = "locked";
1645 
1646         /**
1647          * The subscription to which the message belongs to. Its value will be
1648          * < 0 if the sub id cannot be determined.
1649          * <p>Type: INTEGER (long)</p>
1650          */
1651         public static final String SUBSCRIPTION_ID = "sub_id";
1652 
1653         /**
1654          * The identity of the sender of a sent message. It is
1655          * usually the package name of the app which sends the message.
1656          * <p class="note"><strong>Note:</strong>
1657          * This column is read-only. It is set by the provider and can not be changed by apps.
1658          * <p>Type: TEXT</p>
1659          */
1660         public static final String CREATOR = "creator";
1661     }
1662 
1663     /**
1664      * Columns for the "canonical_addresses" table used by MMS and SMS.
1665      */
1666     public interface CanonicalAddressesColumns extends BaseColumns {
1667         /**
1668          * An address used in MMS or SMS.  Email addresses are
1669          * converted to lower case and are compared by string
1670          * equality.  Other addresses are compared using
1671          * PHONE_NUMBERS_EQUAL.
1672          * <P>Type: TEXT</P>
1673          */
1674         public static final String ADDRESS = "address";
1675     }
1676 
1677     /**
1678      * Columns for the "threads" table used by MMS and SMS.
1679      */
1680     public interface ThreadsColumns extends BaseColumns {
1681 
1682         /**
1683          * The date at which the thread was created.
1684          * <P>Type: INTEGER (long)</P>
1685          */
1686         public static final String DATE = "date";
1687 
1688         /**
1689          * A string encoding of the recipient IDs of the recipients of
1690          * the message, in numerical order and separated by spaces.
1691          * <P>Type: TEXT</P>
1692          */
1693         public static final String RECIPIENT_IDS = "recipient_ids";
1694 
1695         /**
1696          * The message count of the thread.
1697          * <P>Type: INTEGER</P>
1698          */
1699         public static final String MESSAGE_COUNT = "message_count";
1700 
1701         /**
1702          * Indicates whether all messages of the thread have been read.
1703          * <P>Type: INTEGER</P>
1704          */
1705         public static final String READ = "read";
1706 
1707         /**
1708          * The snippet of the latest message in the thread.
1709          * <P>Type: TEXT</P>
1710          */
1711         public static final String SNIPPET = "snippet";
1712 
1713         /**
1714          * The charset of the snippet.
1715          * <P>Type: INTEGER</P>
1716          */
1717         public static final String SNIPPET_CHARSET = "snippet_cs";
1718 
1719         /**
1720          * Type of the thread, either {@link Threads#COMMON_THREAD} or
1721          * {@link Threads#BROADCAST_THREAD}.
1722          * <P>Type: INTEGER</P>
1723          */
1724         public static final String TYPE = "type";
1725 
1726         /**
1727          * Indicates whether there is a transmission error in the thread.
1728          * <P>Type: INTEGER</P>
1729          */
1730         public static final String ERROR = "error";
1731 
1732         /**
1733          * Indicates whether this thread contains any attachments.
1734          * <P>Type: INTEGER</P>
1735          */
1736         public static final String HAS_ATTACHMENT = "has_attachment";
1737 
1738         /**
1739          * If the thread is archived
1740          * <P>Type: INTEGER (boolean)</P>
1741          */
1742         public static final String ARCHIVED = "archived";
1743     }
1744 
1745     /**
1746      * Helper functions for the "threads" table used by MMS and SMS.
1747      */
1748     public static final class Threads implements ThreadsColumns {
1749 
1750         private static final String[] ID_PROJECTION = { BaseColumns._ID };
1751 
1752         /**
1753          * Private {@code content://} style URL for this table. Used by
1754          * {@link #getOrCreateThreadId(android.content.Context, java.util.Set)}.
1755          */
1756         private static final Uri THREAD_ID_CONTENT_URI = Uri.parse(
1757                 "content://mms-sms/threadID");
1758 
1759         /**
1760          * The {@code content://} style URL for this table, by conversation.
1761          */
1762         public static final Uri CONTENT_URI = Uri.withAppendedPath(
1763                 MmsSms.CONTENT_URI, "conversations");
1764 
1765         /**
1766          * The {@code content://} style URL for this table, for obsolete threads.
1767          */
1768         public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(
1769                 CONTENT_URI, "obsolete");
1770 
1771         /** Thread type: common thread. */
1772         public static final int COMMON_THREAD    = 0;
1773 
1774         /** Thread type: broadcast thread. */
1775         public static final int BROADCAST_THREAD = 1;
1776 
1777         /**
1778          * Not instantiable.
1779          * @hide
1780          */
Threads()1781         private Threads() {
1782         }
1783 
1784         /**
1785          * This is a single-recipient version of {@code getOrCreateThreadId}.
1786          * It's convenient for use with SMS messages.
1787          * @param context the context object to use.
1788          * @param recipient the recipient to send to.
1789          * @hide
1790          */
getOrCreateThreadId(Context context, String recipient)1791         public static long getOrCreateThreadId(Context context, String recipient) {
1792             Set<String> recipients = new HashSet<String>();
1793 
1794             recipients.add(recipient);
1795             return getOrCreateThreadId(context, recipients);
1796         }
1797 
1798         /**
1799          * Given the recipients list and subject of an unsaved message,
1800          * return its thread ID.  If the message starts a new thread,
1801          * allocate a new thread ID.  Otherwise, use the appropriate
1802          * existing thread ID.
1803          *
1804          * <p>Find the thread ID of the same set of recipients (in any order,
1805          * without any additions). If one is found, return it. Otherwise,
1806          * return a unique thread ID.</p>
1807          * @hide
1808          */
getOrCreateThreadId( Context context, Set<String> recipients)1809         public static long getOrCreateThreadId(
1810                 Context context, Set<String> recipients) {
1811             Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();
1812 
1813             for (String recipient : recipients) {
1814                 if (Mms.isEmailAddress(recipient)) {
1815                     recipient = Mms.extractAddrSpec(recipient);
1816                 }
1817 
1818                 uriBuilder.appendQueryParameter("recipient", recipient);
1819             }
1820 
1821             Uri uri = uriBuilder.build();
1822             //if (DEBUG) Rlog.v(TAG, "getOrCreateThreadId uri: " + uri);
1823 
1824             Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
1825                     uri, ID_PROJECTION, null, null, null);
1826             if (cursor != null) {
1827                 try {
1828                     if (cursor.moveToFirst()) {
1829                         return cursor.getLong(0);
1830                     } else {
1831                         Rlog.e(TAG, "getOrCreateThreadId returned no rows!");
1832                     }
1833                 } finally {
1834                     cursor.close();
1835                 }
1836             }
1837 
1838             Rlog.e(TAG, "getOrCreateThreadId failed with " + recipients.size() + " recipients");
1839             throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
1840         }
1841     }
1842 
1843     /**
1844      * Contains all MMS messages.
1845      */
1846     public static final class Mms implements BaseMmsColumns {
1847 
1848         /**
1849          * Not instantiable.
1850          * @hide
1851          */
Mms()1852         private Mms() {
1853         }
1854 
1855         /**
1856          * The {@code content://} URI for this table.
1857          */
1858         public static final Uri CONTENT_URI = Uri.parse("content://mms");
1859 
1860         /**
1861          * Content URI for getting MMS report requests.
1862          */
1863         public static final Uri REPORT_REQUEST_URI = Uri.withAppendedPath(
1864                                             CONTENT_URI, "report-request");
1865 
1866         /**
1867          * Content URI for getting MMS report status.
1868          */
1869         public static final Uri REPORT_STATUS_URI = Uri.withAppendedPath(
1870                                             CONTENT_URI, "report-status");
1871 
1872         /**
1873          * The default sort order for this table.
1874          */
1875         public static final String DEFAULT_SORT_ORDER = "date DESC";
1876 
1877         /**
1878          * Regex pattern for names and email addresses.
1879          * <ul>
1880          *     <li><em>mailbox</em> = {@code name-addr}</li>
1881          *     <li><em>name-addr</em> = {@code [display-name] angle-addr}</li>
1882          *     <li><em>angle-addr</em> = {@code [CFWS] "<" addr-spec ">" [CFWS]}</li>
1883          * </ul>
1884          * @hide
1885          */
1886         public static final Pattern NAME_ADDR_EMAIL_PATTERN =
1887                 Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");
1888 
1889         /**
1890          * Helper method to query this table.
1891          * @hide
1892          */
query( ContentResolver cr, String[] projection)1893         public static Cursor query(
1894                 ContentResolver cr, String[] projection) {
1895             return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
1896         }
1897 
1898         /**
1899          * Helper method to query this table.
1900          * @hide
1901          */
query( ContentResolver cr, String[] projection, String where, String orderBy)1902         public static Cursor query(
1903                 ContentResolver cr, String[] projection,
1904                 String where, String orderBy) {
1905             return cr.query(CONTENT_URI, projection,
1906                     where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
1907         }
1908 
1909         /**
1910          * Helper method to extract email address from address string.
1911          * @hide
1912          */
extractAddrSpec(String address)1913         public static String extractAddrSpec(String address) {
1914             Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);
1915 
1916             if (match.matches()) {
1917                 return match.group(2);
1918             }
1919             return address;
1920         }
1921 
1922         /**
1923          * Is the specified address an email address?
1924          *
1925          * @param address the input address to test
1926          * @return true if address is an email address; false otherwise.
1927          * @hide
1928          */
isEmailAddress(String address)1929         public static boolean isEmailAddress(String address) {
1930             if (TextUtils.isEmpty(address)) {
1931                 return false;
1932             }
1933 
1934             String s = extractAddrSpec(address);
1935             Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
1936             return match.matches();
1937         }
1938 
1939         /**
1940          * Is the specified number a phone number?
1941          *
1942          * @param number the input number to test
1943          * @return true if number is a phone number; false otherwise.
1944          * @hide
1945          */
isPhoneNumber(String number)1946         public static boolean isPhoneNumber(String number) {
1947             if (TextUtils.isEmpty(number)) {
1948                 return false;
1949             }
1950 
1951             Matcher match = Patterns.PHONE.matcher(number);
1952             return match.matches();
1953         }
1954 
1955         /**
1956          * Contains all MMS messages in the MMS app inbox.
1957          */
1958         public static final class Inbox implements BaseMmsColumns {
1959 
1960             /**
1961              * Not instantiable.
1962              * @hide
1963              */
Inbox()1964             private Inbox() {
1965             }
1966 
1967             /**
1968              * The {@code content://} style URL for this table.
1969              */
1970             public static final Uri
1971                     CONTENT_URI = Uri.parse("content://mms/inbox");
1972 
1973             /**
1974              * The default sort order for this table.
1975              */
1976             public static final String DEFAULT_SORT_ORDER = "date DESC";
1977         }
1978 
1979         /**
1980          * Contains all MMS messages in the MMS app sent folder.
1981          */
1982         public static final class Sent implements BaseMmsColumns {
1983 
1984             /**
1985              * Not instantiable.
1986              * @hide
1987              */
Sent()1988             private Sent() {
1989             }
1990 
1991             /**
1992              * The {@code content://} style URL for this table.
1993              */
1994             public static final Uri
1995                     CONTENT_URI = Uri.parse("content://mms/sent");
1996 
1997             /**
1998              * The default sort order for this table.
1999              */
2000             public static final String DEFAULT_SORT_ORDER = "date DESC";
2001         }
2002 
2003         /**
2004          * Contains all MMS messages in the MMS app drafts folder.
2005          */
2006         public static final class Draft implements BaseMmsColumns {
2007 
2008             /**
2009              * Not instantiable.
2010              * @hide
2011              */
Draft()2012             private Draft() {
2013             }
2014 
2015             /**
2016              * The {@code content://} style URL for this table.
2017              */
2018             public static final Uri
2019                     CONTENT_URI = Uri.parse("content://mms/drafts");
2020 
2021             /**
2022              * The default sort order for this table.
2023              */
2024             public static final String DEFAULT_SORT_ORDER = "date DESC";
2025         }
2026 
2027         /**
2028          * Contains all MMS messages in the MMS app outbox.
2029          */
2030         public static final class Outbox implements BaseMmsColumns {
2031 
2032             /**
2033              * Not instantiable.
2034              * @hide
2035              */
Outbox()2036             private Outbox() {
2037             }
2038 
2039             /**
2040              * The {@code content://} style URL for this table.
2041              */
2042             public static final Uri
2043                     CONTENT_URI = Uri.parse("content://mms/outbox");
2044 
2045             /**
2046              * The default sort order for this table.
2047              */
2048             public static final String DEFAULT_SORT_ORDER = "date DESC";
2049         }
2050 
2051         /**
2052          * Contains address information for an MMS message.
2053          */
2054         public static final class Addr implements BaseColumns {
2055 
2056             /**
2057              * Not instantiable.
2058              * @hide
2059              */
Addr()2060             private Addr() {
2061             }
2062 
2063             /**
2064              * The ID of MM which this address entry belongs to.
2065              * <P>Type: INTEGER (long)</P>
2066              */
2067             public static final String MSG_ID = "msg_id";
2068 
2069             /**
2070              * The ID of contact entry in Phone Book.
2071              * <P>Type: INTEGER (long)</P>
2072              */
2073             public static final String CONTACT_ID = "contact_id";
2074 
2075             /**
2076              * The address text.
2077              * <P>Type: TEXT</P>
2078              */
2079             public static final String ADDRESS = "address";
2080 
2081             /**
2082              * Type of address: must be one of {@code PduHeaders.BCC},
2083              * {@code PduHeaders.CC}, {@code PduHeaders.FROM}, {@code PduHeaders.TO}.
2084              * <P>Type: INTEGER</P>
2085              */
2086             public static final String TYPE = "type";
2087 
2088             /**
2089              * Character set of this entry (MMS charset value).
2090              * <P>Type: INTEGER</P>
2091              */
2092             public static final String CHARSET = "charset";
2093         }
2094 
2095         /**
2096          * Contains message parts.
2097          */
2098         public static final class Part implements BaseColumns {
2099 
2100             /**
2101              * Not instantiable.
2102              * @hide
2103              */
Part()2104             private Part() {
2105             }
2106 
2107             /**
2108              * The identifier of the message which this part belongs to.
2109              * <P>Type: INTEGER</P>
2110              */
2111             public static final String MSG_ID = "mid";
2112 
2113             /**
2114              * The order of the part.
2115              * <P>Type: INTEGER</P>
2116              */
2117             public static final String SEQ = "seq";
2118 
2119             /**
2120              * The content type of the part.
2121              * <P>Type: TEXT</P>
2122              */
2123             public static final String CONTENT_TYPE = "ct";
2124 
2125             /**
2126              * The name of the part.
2127              * <P>Type: TEXT</P>
2128              */
2129             public static final String NAME = "name";
2130 
2131             /**
2132              * The charset of the part.
2133              * <P>Type: TEXT</P>
2134              */
2135             public static final String CHARSET = "chset";
2136 
2137             /**
2138              * The file name of the part.
2139              * <P>Type: TEXT</P>
2140              */
2141             public static final String FILENAME = "fn";
2142 
2143             /**
2144              * The content disposition of the part.
2145              * <P>Type: TEXT</P>
2146              */
2147             public static final String CONTENT_DISPOSITION = "cd";
2148 
2149             /**
2150              * The content ID of the part.
2151              * <P>Type: INTEGER</P>
2152              */
2153             public static final String CONTENT_ID = "cid";
2154 
2155             /**
2156              * The content location of the part.
2157              * <P>Type: INTEGER</P>
2158              */
2159             public static final String CONTENT_LOCATION = "cl";
2160 
2161             /**
2162              * The start of content-type of the message.
2163              * <P>Type: INTEGER</P>
2164              */
2165             public static final String CT_START = "ctt_s";
2166 
2167             /**
2168              * The type of content-type of the message.
2169              * <P>Type: TEXT</P>
2170              */
2171             public static final String CT_TYPE = "ctt_t";
2172 
2173             /**
2174              * The location (on filesystem) of the binary data of the part.
2175              * <P>Type: INTEGER</P>
2176              */
2177             public static final String _DATA = "_data";
2178 
2179             /**
2180              * The message text.
2181              * <P>Type: TEXT</P>
2182              */
2183             public static final String TEXT = "text";
2184         }
2185 
2186         /**
2187          * Message send rate table.
2188          */
2189         public static final class Rate {
2190 
2191             /**
2192              * Not instantiable.
2193              * @hide
2194              */
Rate()2195             private Rate() {
2196             }
2197 
2198             /**
2199              * The {@code content://} style URL for this table.
2200              */
2201             public static final Uri CONTENT_URI = Uri.withAppendedPath(
2202                     Mms.CONTENT_URI, "rate");
2203 
2204             /**
2205              * When a message was successfully sent.
2206              * <P>Type: INTEGER (long)</P>
2207              */
2208             public static final String SENT_TIME = "sent_time";
2209         }
2210 
2211         /**
2212          * Intents class.
2213          */
2214         public static final class Intents {
2215 
2216             /**
2217              * Not instantiable.
2218              * @hide
2219              */
Intents()2220             private Intents() {
2221             }
2222 
2223             /**
2224              * Indicates that the contents of specified URIs were changed.
2225              * The application which is showing or caching these contents
2226              * should be updated.
2227              */
2228             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
2229             public static final String CONTENT_CHANGED_ACTION
2230                     = "android.intent.action.CONTENT_CHANGED";
2231 
2232             /**
2233              * An extra field which stores the URI of deleted contents.
2234              */
2235             public static final String DELETED_CONTENTS = "deleted_contents";
2236         }
2237     }
2238 
2239     /**
2240      * Contains all MMS and SMS messages.
2241      */
2242     public static final class MmsSms implements BaseColumns {
2243 
2244         /**
2245          * Not instantiable.
2246          * @hide
2247          */
MmsSms()2248         private MmsSms() {
2249         }
2250 
2251         /**
2252          * The column to distinguish SMS and MMS messages in query results.
2253          */
2254         public static final String TYPE_DISCRIMINATOR_COLUMN =
2255                 "transport_type";
2256 
2257         /**
2258          * The {@code content://} style URL for this table.
2259          */
2260         public static final Uri CONTENT_URI = Uri.parse("content://mms-sms/");
2261 
2262         /**
2263          * The {@code content://} style URL for this table, by conversation.
2264          */
2265         public static final Uri CONTENT_CONVERSATIONS_URI = Uri.parse(
2266                 "content://mms-sms/conversations");
2267 
2268         /**
2269          * The {@code content://} style URL for this table, by phone number.
2270          */
2271         public static final Uri CONTENT_FILTER_BYPHONE_URI = Uri.parse(
2272                 "content://mms-sms/messages/byphone");
2273 
2274         /**
2275          * The {@code content://} style URL for undelivered messages in this table.
2276          */
2277         public static final Uri CONTENT_UNDELIVERED_URI = Uri.parse(
2278                 "content://mms-sms/undelivered");
2279 
2280         /**
2281          * The {@code content://} style URL for draft messages in this table.
2282          */
2283         public static final Uri CONTENT_DRAFT_URI = Uri.parse(
2284                 "content://mms-sms/draft");
2285 
2286         /**
2287          * The {@code content://} style URL for locked messages in this table.
2288          */
2289         public static final Uri CONTENT_LOCKED_URI = Uri.parse(
2290                 "content://mms-sms/locked");
2291 
2292         /**
2293          * Pass in a query parameter called "pattern" which is the text to search for.
2294          * The sort order is fixed to be: {@code thread_id ASC, date DESC}.
2295          */
2296         public static final Uri SEARCH_URI = Uri.parse(
2297                 "content://mms-sms/search");
2298 
2299         // Constants for message protocol types.
2300 
2301         /** SMS protocol type. */
2302         public static final int SMS_PROTO = 0;
2303 
2304         /** MMS protocol type. */
2305         public static final int MMS_PROTO = 1;
2306 
2307         // Constants for error types of pending messages.
2308 
2309         /** Error type: no error. */
2310         public static final int NO_ERROR                      = 0;
2311 
2312         /** Error type: generic transient error. */
2313         public static final int ERR_TYPE_GENERIC              = 1;
2314 
2315         /** Error type: SMS protocol transient error. */
2316         public static final int ERR_TYPE_SMS_PROTO_TRANSIENT  = 2;
2317 
2318         /** Error type: MMS protocol transient error. */
2319         public static final int ERR_TYPE_MMS_PROTO_TRANSIENT  = 3;
2320 
2321         /** Error type: transport failure. */
2322         public static final int ERR_TYPE_TRANSPORT_FAILURE    = 4;
2323 
2324         /** Error type: permanent error (along with all higher error values). */
2325         public static final int ERR_TYPE_GENERIC_PERMANENT    = 10;
2326 
2327         /** Error type: SMS protocol permanent error. */
2328         public static final int ERR_TYPE_SMS_PROTO_PERMANENT  = 11;
2329 
2330         /** Error type: MMS protocol permanent error. */
2331         public static final int ERR_TYPE_MMS_PROTO_PERMANENT  = 12;
2332 
2333         /**
2334          * Contains pending messages info.
2335          */
2336         public static final class PendingMessages implements BaseColumns {
2337 
2338             /**
2339              * Not instantiable.
2340              * @hide
2341              */
PendingMessages()2342             private PendingMessages() {
2343             }
2344 
2345             public static final Uri CONTENT_URI = Uri.withAppendedPath(
2346                     MmsSms.CONTENT_URI, "pending");
2347 
2348             /**
2349              * The type of transport protocol (MMS or SMS).
2350              * <P>Type: INTEGER</P>
2351              */
2352             public static final String PROTO_TYPE = "proto_type";
2353 
2354             /**
2355              * The ID of the message to be sent or downloaded.
2356              * <P>Type: INTEGER (long)</P>
2357              */
2358             public static final String MSG_ID = "msg_id";
2359 
2360             /**
2361              * The type of the message to be sent or downloaded.
2362              * This field is only valid for MM. For SM, its value is always set to 0.
2363              * <P>Type: INTEGER</P>
2364              */
2365             public static final String MSG_TYPE = "msg_type";
2366 
2367             /**
2368              * The type of the error code.
2369              * <P>Type: INTEGER</P>
2370              */
2371             public static final String ERROR_TYPE = "err_type";
2372 
2373             /**
2374              * The error code of sending/retrieving process.
2375              * <P>Type: INTEGER</P>
2376              */
2377             public static final String ERROR_CODE = "err_code";
2378 
2379             /**
2380              * How many times we tried to send or download the message.
2381              * <P>Type: INTEGER</P>
2382              */
2383             public static final String RETRY_INDEX = "retry_index";
2384 
2385             /**
2386              * The time to do next retry.
2387              * <P>Type: INTEGER (long)</P>
2388              */
2389             public static final String DUE_TIME = "due_time";
2390 
2391             /**
2392              * The time we last tried to send or download the message.
2393              * <P>Type: INTEGER (long)</P>
2394              */
2395             public static final String LAST_TRY = "last_try";
2396 
2397             /**
2398              * The subscription to which the message belongs to. Its value will be
2399              * < 0 if the sub id cannot be determined.
2400              * <p>Type: INTEGER (long) </p>
2401              */
2402             public static final String SUBSCRIPTION_ID = "pending_sub_id";
2403         }
2404 
2405         /**
2406          * Words table used by provider for full-text searches.
2407          * @hide
2408          */
2409         public static final class WordsTable {
2410 
2411             /**
2412              * Not instantiable.
2413              * @hide
2414              */
WordsTable()2415             private WordsTable() {}
2416 
2417             /**
2418              * Primary key.
2419              * <P>Type: INTEGER (long)</P>
2420              */
2421             public static final String ID = "_id";
2422 
2423             /**
2424              * Source row ID.
2425              * <P>Type: INTEGER (long)</P>
2426              */
2427             public static final String SOURCE_ROW_ID = "source_id";
2428 
2429             /**
2430              * Table ID (either 1 or 2).
2431              * <P>Type: INTEGER</P>
2432              */
2433             public static final String TABLE_ID = "table_to_use";
2434 
2435             /**
2436              * The words to index.
2437              * <P>Type: TEXT</P>
2438              */
2439             public static final String INDEXED_TEXT = "index_text";
2440         }
2441     }
2442 
2443     /**
2444      * Carriers class contains information about APNs, including MMSC information.
2445      */
2446     public static final class Carriers implements BaseColumns {
2447 
2448         /**
2449          * Not instantiable.
2450          * @hide
2451          */
Carriers()2452         private Carriers() {}
2453 
2454         /**
2455          * The {@code content://} style URL for this table.
2456          */
2457         public static final Uri CONTENT_URI = Uri.parse("content://telephony/carriers");
2458 
2459         /**
2460          * The default sort order for this table.
2461          */
2462         public static final String DEFAULT_SORT_ORDER = "name ASC";
2463 
2464         /**
2465          * Entry name.
2466          * <P>Type: TEXT</P>
2467          */
2468         public static final String NAME = "name";
2469 
2470         /**
2471          * APN name.
2472          * <P>Type: TEXT</P>
2473          */
2474         public static final String APN = "apn";
2475 
2476         /**
2477          * Proxy address.
2478          * <P>Type: TEXT</P>
2479          */
2480         public static final String PROXY = "proxy";
2481 
2482         /**
2483          * Proxy port.
2484          * <P>Type: TEXT</P>
2485          */
2486         public static final String PORT = "port";
2487 
2488         /**
2489          * MMS proxy address.
2490          * <P>Type: TEXT</P>
2491          */
2492         public static final String MMSPROXY = "mmsproxy";
2493 
2494         /**
2495          * MMS proxy port.
2496          * <P>Type: TEXT</P>
2497          */
2498         public static final String MMSPORT = "mmsport";
2499 
2500         /**
2501          * Server address.
2502          * <P>Type: TEXT</P>
2503          */
2504         public static final String SERVER = "server";
2505 
2506         /**
2507          * APN username.
2508          * <P>Type: TEXT</P>
2509          */
2510         public static final String USER = "user";
2511 
2512         /**
2513          * APN password.
2514          * <P>Type: TEXT</P>
2515          */
2516         public static final String PASSWORD = "password";
2517 
2518         /**
2519          * MMSC URL.
2520          * <P>Type: TEXT</P>
2521          */
2522         public static final String MMSC = "mmsc";
2523 
2524         /**
2525          * Mobile Country Code (MCC).
2526          * <P>Type: TEXT</P>
2527          */
2528         public static final String MCC = "mcc";
2529 
2530         /**
2531          * Mobile Network Code (MNC).
2532          * <P>Type: TEXT</P>
2533          */
2534         public static final String MNC = "mnc";
2535 
2536         /**
2537          * Numeric operator ID (as String). Usually {@code MCC + MNC}.
2538          * <P>Type: TEXT</P>
2539          */
2540         public static final String NUMERIC = "numeric";
2541 
2542         /**
2543          * Authentication type.
2544          * <P>Type:  INTEGER</P>
2545          */
2546         public static final String AUTH_TYPE = "authtype";
2547 
2548         /**
2549          * Comma-delimited list of APN types.
2550          * <P>Type: TEXT</P>
2551          */
2552         public static final String TYPE = "type";
2553 
2554         /**
2555          * The protocol to use to connect to this APN.
2556          *
2557          * One of the {@code PDP_type} values in TS 27.007 section 10.1.1.
2558          * For example: {@code IP}, {@code IPV6}, {@code IPV4V6}, or {@code PPP}.
2559          * <P>Type: TEXT</P>
2560          */
2561         public static final String PROTOCOL = "protocol";
2562 
2563         /**
2564          * The protocol to use to connect to this APN when roaming.
2565          * The syntax is the same as protocol.
2566          * <P>Type: TEXT</P>
2567          */
2568         public static final String ROAMING_PROTOCOL = "roaming_protocol";
2569 
2570         /**
2571          * Is this the current APN?
2572          * <P>Type: INTEGER (boolean)</P>
2573          */
2574         public static final String CURRENT = "current";
2575 
2576         /**
2577          * Is this APN enabled?
2578          * <P>Type: INTEGER (boolean)</P>
2579          */
2580         public static final String CARRIER_ENABLED = "carrier_enabled";
2581 
2582         /**
2583          * Radio Access Technology info.
2584          * To check what values are allowed, refer to {@link android.telephony.ServiceState}.
2585          * This should be spread to other technologies,
2586          * but is currently only used for LTE (14) and eHRPD (13).
2587          * <P>Type: INTEGER</P>
2588          */
2589         public static final String BEARER = "bearer";
2590 
2591         /**
2592          * MVNO type:
2593          * {@code SPN (Service Provider Name), IMSI, GID (Group Identifier Level 1)}.
2594          * <P>Type: TEXT</P>
2595          */
2596         public static final String MVNO_TYPE = "mvno_type";
2597 
2598         /**
2599          * MVNO data.
2600          * Use the following examples.
2601          * <ul>
2602          *     <li>SPN: A MOBILE, BEN NL, ...</li>
2603          *     <li>IMSI: 302720x94, 2060188, ...</li>
2604          *     <li>GID: 4E, 33, ...</li>
2605          * </ul>
2606          * <P>Type: TEXT</P>
2607          */
2608         public static final String MVNO_MATCH_DATA = "mvno_match_data";
2609 
2610         /**
2611          * The subscription to which the APN belongs to
2612          * <p>Type: INTEGER (long) </p>
2613          */
2614         public static final String SUBSCRIPTION_ID = "sub_id";
2615 
2616         /**
2617          * The profile_id to which the APN saved in modem
2618          * <p>Type: INTEGER</p>
2619          *@hide
2620          */
2621         public static final String PROFILE_ID = "profile_id";
2622 
2623         /**
2624          * Is the apn setting to be set in modem
2625          * <P>Type: INTEGER (boolean)</P>
2626          *@hide
2627          */
2628         public static final String MODEM_COGNITIVE = "modem_cognitive";
2629 
2630         /**
2631          * The max connections of this apn
2632          * <p>Type: INTEGER</p>
2633          *@hide
2634          */
2635         public static final String MAX_CONNS = "max_conns";
2636 
2637         /**
2638          * The wait time for retry of the apn
2639          * <p>Type: INTEGER</p>
2640          *@hide
2641          */
2642         public static final String WAIT_TIME = "wait_time";
2643 
2644         /**
2645          * The time to limit max connection for the apn
2646          * <p>Type: INTEGER</p>
2647          *@hide
2648          */
2649         public static final String MAX_CONNS_TIME = "max_conns_time";
2650 
2651         /**
2652          * The MTU size of the mobile interface to  which the APN connected
2653          * <p>Type: INTEGER </p>
2654          * @hide
2655          */
2656         public static final String MTU = "mtu";
2657     }
2658 
2659     /**
2660      * Contains received SMS cell broadcast messages.
2661      * @hide
2662      */
2663     public static final class CellBroadcasts implements BaseColumns {
2664 
2665         /**
2666          * Not instantiable.
2667          * @hide
2668          */
CellBroadcasts()2669         private CellBroadcasts() {}
2670 
2671         /**
2672          * The {@code content://} URI for this table.
2673          */
2674         public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts");
2675 
2676         /**
2677          * Message geographical scope.
2678          * <P>Type: INTEGER</P>
2679          */
2680         public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
2681 
2682         /**
2683          * Message serial number.
2684          * <P>Type: INTEGER</P>
2685          */
2686         public static final String SERIAL_NUMBER = "serial_number";
2687 
2688         /**
2689          * PLMN of broadcast sender. {@code SERIAL_NUMBER + PLMN + LAC + CID} uniquely identifies
2690          * a broadcast for duplicate detection purposes.
2691          * <P>Type: TEXT</P>
2692          */
2693         public static final String PLMN = "plmn";
2694 
2695         /**
2696          * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA.
2697          * Only included if Geographical Scope of message is not PLMN wide (01).
2698          * <P>Type: INTEGER</P>
2699          */
2700         public static final String LAC = "lac";
2701 
2702         /**
2703          * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the
2704          * Geographical Scope of message is cell wide (00 or 11).
2705          * <P>Type: INTEGER</P>
2706          */
2707         public static final String CID = "cid";
2708 
2709         /**
2710          * Message code. <em>OBSOLETE: merged into SERIAL_NUMBER.</em>
2711          * <P>Type: INTEGER</P>
2712          */
2713         public static final String V1_MESSAGE_CODE = "message_code";
2714 
2715         /**
2716          * Message identifier. <em>OBSOLETE: renamed to SERVICE_CATEGORY.</em>
2717          * <P>Type: INTEGER</P>
2718          */
2719         public static final String V1_MESSAGE_IDENTIFIER = "message_id";
2720 
2721         /**
2722          * Service category (GSM/UMTS: message identifier; CDMA: service category).
2723          * <P>Type: INTEGER</P>
2724          */
2725         public static final String SERVICE_CATEGORY = "service_category";
2726 
2727         /**
2728          * Message language code.
2729          * <P>Type: TEXT</P>
2730          */
2731         public static final String LANGUAGE_CODE = "language";
2732 
2733         /**
2734          * Message body.
2735          * <P>Type: TEXT</P>
2736          */
2737         public static final String MESSAGE_BODY = "body";
2738 
2739         /**
2740          * Message delivery time.
2741          * <P>Type: INTEGER (long)</P>
2742          */
2743         public static final String DELIVERY_TIME = "date";
2744 
2745         /**
2746          * Has the message been viewed?
2747          * <P>Type: INTEGER (boolean)</P>
2748          */
2749         public static final String MESSAGE_READ = "read";
2750 
2751         /**
2752          * Message format (3GPP or 3GPP2).
2753          * <P>Type: INTEGER</P>
2754          */
2755         public static final String MESSAGE_FORMAT = "format";
2756 
2757         /**
2758          * Message priority (including emergency).
2759          * <P>Type: INTEGER</P>
2760          */
2761         public static final String MESSAGE_PRIORITY = "priority";
2762 
2763         /**
2764          * ETWS warning type (ETWS alerts only).
2765          * <P>Type: INTEGER</P>
2766          */
2767         public static final String ETWS_WARNING_TYPE = "etws_warning_type";
2768 
2769         /**
2770          * CMAS message class (CMAS alerts only).
2771          * <P>Type: INTEGER</P>
2772          */
2773         public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
2774 
2775         /**
2776          * CMAS category (CMAS alerts only).
2777          * <P>Type: INTEGER</P>
2778          */
2779         public static final String CMAS_CATEGORY = "cmas_category";
2780 
2781         /**
2782          * CMAS response type (CMAS alerts only).
2783          * <P>Type: INTEGER</P>
2784          */
2785         public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
2786 
2787         /**
2788          * CMAS severity (CMAS alerts only).
2789          * <P>Type: INTEGER</P>
2790          */
2791         public static final String CMAS_SEVERITY = "cmas_severity";
2792 
2793         /**
2794          * CMAS urgency (CMAS alerts only).
2795          * <P>Type: INTEGER</P>
2796          */
2797         public static final String CMAS_URGENCY = "cmas_urgency";
2798 
2799         /**
2800          * CMAS certainty (CMAS alerts only).
2801          * <P>Type: INTEGER</P>
2802          */
2803         public static final String CMAS_CERTAINTY = "cmas_certainty";
2804 
2805         /** The default sort order for this table. */
2806         public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
2807 
2808         /**
2809          * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
2810          */
2811         public static final String[] QUERY_COLUMNS = {
2812                 _ID,
2813                 GEOGRAPHICAL_SCOPE,
2814                 PLMN,
2815                 LAC,
2816                 CID,
2817                 SERIAL_NUMBER,
2818                 SERVICE_CATEGORY,
2819                 LANGUAGE_CODE,
2820                 MESSAGE_BODY,
2821                 DELIVERY_TIME,
2822                 MESSAGE_READ,
2823                 MESSAGE_FORMAT,
2824                 MESSAGE_PRIORITY,
2825                 ETWS_WARNING_TYPE,
2826                 CMAS_MESSAGE_CLASS,
2827                 CMAS_CATEGORY,
2828                 CMAS_RESPONSE_TYPE,
2829                 CMAS_SEVERITY,
2830                 CMAS_URGENCY,
2831                 CMAS_CERTAINTY
2832         };
2833     }
2834 }
2835