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