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