• 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.content.ContentResolver;
22 import android.content.ContentValues;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.database.Cursor;
26 import android.database.sqlite.SqliteWrapper;
27 import android.net.Uri;
28 import android.telephony.SmsMessage;
29 import android.text.TextUtils;
30 import android.telephony.Rlog;
31 import android.util.Patterns;
32 
33 
34 import java.util.HashSet;
35 import java.util.Set;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38 
39 /**
40  * The Telephony provider contains data related to phone operation.
41  *
42  * @hide
43  */
44 public final class Telephony {
45     private static final String TAG = "Telephony";
46 
47     // Constructor
Telephony()48     public Telephony() {
49     }
50 
51     /**
52      * Base columns for tables that contain text based SMSs.
53      */
54     public interface TextBasedSmsColumns {
55         /**
56          * The type of the message
57          * <P>Type: INTEGER</P>
58          */
59         public static final String TYPE = "type";
60 
61         public static final int MESSAGE_TYPE_ALL    = 0;
62         public static final int MESSAGE_TYPE_INBOX  = 1;
63         public static final int MESSAGE_TYPE_SENT   = 2;
64         public static final int MESSAGE_TYPE_DRAFT  = 3;
65         public static final int MESSAGE_TYPE_OUTBOX = 4;
66         public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages
67         public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send later
68 
69 
70         /**
71          * The thread ID of the message
72          * <P>Type: INTEGER</P>
73          */
74         public static final String THREAD_ID = "thread_id";
75 
76         /**
77          * The address of the other party
78          * <P>Type: TEXT</P>
79          */
80         public static final String ADDRESS = "address";
81 
82         /**
83          * The person ID of the sender
84          * <P>Type: INTEGER (long)</P>
85          */
86         public static final String PERSON_ID = "person";
87 
88         /**
89          * The date the message was received
90          * <P>Type: INTEGER (long)</P>
91          */
92         public static final String DATE = "date";
93 
94         /**
95          * The date the message was sent
96          * <P>Type: INTEGER (long)</P>
97          */
98         public static final String DATE_SENT = "date_sent";
99 
100         /**
101          * Has the message been read
102          * <P>Type: INTEGER (boolean)</P>
103          */
104         public static final String READ = "read";
105 
106         /**
107          * Indicates whether this message has been seen by the user. The "seen" flag will be
108          * used to figure out whether we need to throw up a statusbar notification or not.
109          */
110         public static final String SEEN = "seen";
111 
112         /**
113          * The TP-Status value for the message, or -1 if no status has
114          * been received
115          */
116         public static final String STATUS = "status";
117 
118         public static final int STATUS_NONE = -1;
119         public static final int STATUS_COMPLETE = 0;
120         public static final int STATUS_PENDING = 32;
121         public static final int STATUS_FAILED = 64;
122 
123         /**
124          * The subject of the message, if present
125          * <P>Type: TEXT</P>
126          */
127         public static final String SUBJECT = "subject";
128 
129         /**
130          * The body of the message
131          * <P>Type: TEXT</P>
132          */
133         public static final String BODY = "body";
134 
135         /**
136          * The id of the sender of the conversation, if present
137          * <P>Type: INTEGER (reference to item in content://contacts/people)</P>
138          */
139         public static final String PERSON = "person";
140 
141         /**
142          * The protocol identifier code
143          * <P>Type: INTEGER</P>
144          */
145         public static final String PROTOCOL = "protocol";
146 
147         /**
148          * Whether the <code>TP-Reply-Path</code> bit was set on this message
149          * <P>Type: BOOLEAN</P>
150          */
151         public static final String REPLY_PATH_PRESENT = "reply_path_present";
152 
153         /**
154          * The service center (SC) through which to send the message, if present
155          * <P>Type: TEXT</P>
156          */
157         public static final String SERVICE_CENTER = "service_center";
158 
159         /**
160          * Has the message been locked?
161          * <P>Type: INTEGER (boolean)</P>
162          */
163         public static final String LOCKED = "locked";
164 
165         /**
166          * Error code associated with sending or receiving this message
167          * <P>Type: INTEGER</P>
168          */
169         public static final String ERROR_CODE = "error_code";
170 
171         /**
172          * Meta data used externally.
173          * <P>Type: TEXT</P>
174          */
175         public static final String META_DATA = "meta_data";
176     }
177 
178     /**
179      * Contains all text based SMS messages.
180      */
181     public static final class Sms implements BaseColumns, TextBasedSmsColumns {
query(ContentResolver cr, String[] projection)182         public static final Cursor query(ContentResolver cr, String[] projection) {
183             return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
184         }
185 
query(ContentResolver cr, String[] projection, String where, String orderBy)186         public static final Cursor query(ContentResolver cr, String[] projection,
187                 String where, String orderBy) {
188             return cr.query(CONTENT_URI, projection, where,
189                                          null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
190         }
191 
192         /**
193          * The content:// style URL for this table
194          */
195         public static final Uri CONTENT_URI =
196             Uri.parse("content://sms");
197 
198         /**
199          * The default sort order for this table
200          */
201         public static final String DEFAULT_SORT_ORDER = "date DESC";
202 
203         /**
204          * Add an SMS to the given URI.
205          *
206          * @param resolver the content resolver to use
207          * @param uri the URI to add the message to
208          * @param address the address of the sender
209          * @param body the body of the message
210          * @param subject the psuedo-subject of the message
211          * @param date the timestamp for the message
212          * @param read true if the message has been read, false if not
213          * @param deliveryReport true if a delivery report was requested, false if not
214          * @return the URI for the new message
215          */
addMessageToUri(ContentResolver resolver, Uri uri, String address, String body, String subject, Long date, boolean read, boolean deliveryReport)216         public static Uri addMessageToUri(ContentResolver resolver,
217                 Uri uri, String address, String body, String subject,
218                 Long date, boolean read, boolean deliveryReport) {
219             return addMessageToUri(resolver, uri, address, body, subject,
220                     date, read, deliveryReport, -1L);
221         }
222 
223         /**
224          * Add an SMS to the given URI with thread_id specified.
225          *
226          * @param resolver the content resolver to use
227          * @param uri the URI to add the message to
228          * @param address the address of the sender
229          * @param body the body of the message
230          * @param subject the psuedo-subject of the message
231          * @param date the timestamp for the message
232          * @param read true if the message has been read, false if not
233          * @param deliveryReport true if a delivery report was requested, false if not
234          * @param threadId the thread_id of the message
235          * @return the URI for the new message
236          */
addMessageToUri(ContentResolver resolver, Uri uri, String address, String body, String subject, Long date, boolean read, boolean deliveryReport, long threadId)237         public static Uri addMessageToUri(ContentResolver resolver,
238                 Uri uri, String address, String body, String subject,
239                 Long date, boolean read, boolean deliveryReport, long threadId) {
240             ContentValues values = new ContentValues(7);
241 
242             values.put(ADDRESS, address);
243             if (date != null) {
244                 values.put(DATE, date);
245             }
246             values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
247             values.put(SUBJECT, subject);
248             values.put(BODY, body);
249             if (deliveryReport) {
250                 values.put(STATUS, STATUS_PENDING);
251             }
252             if (threadId != -1L) {
253                 values.put(THREAD_ID, threadId);
254             }
255             return resolver.insert(uri, values);
256         }
257 
258         /**
259          * Move a message to the given folder.
260          *
261          * @param context the context to use
262          * @param uri the message to move
263          * @param folder the folder to move to
264          * @return true if the operation succeeded
265          */
moveMessageToFolder(Context context, Uri uri, int folder, int error)266         public static boolean moveMessageToFolder(Context context,
267                 Uri uri, int folder, int error) {
268             if (uri == null) {
269                 return false;
270             }
271 
272             boolean markAsUnread = false;
273             boolean markAsRead = false;
274             switch(folder) {
275             case MESSAGE_TYPE_INBOX:
276             case MESSAGE_TYPE_DRAFT:
277                 break;
278             case MESSAGE_TYPE_OUTBOX:
279             case MESSAGE_TYPE_SENT:
280                 markAsRead = true;
281                 break;
282             case MESSAGE_TYPE_FAILED:
283             case MESSAGE_TYPE_QUEUED:
284                 markAsUnread = true;
285                 break;
286             default:
287                 return false;
288             }
289 
290             ContentValues values = new ContentValues(3);
291 
292             values.put(TYPE, folder);
293             if (markAsUnread) {
294                 values.put(READ, Integer.valueOf(0));
295             } else if (markAsRead) {
296                 values.put(READ, Integer.valueOf(1));
297             }
298             values.put(ERROR_CODE, error);
299 
300             return 1 == SqliteWrapper.update(context, context.getContentResolver(),
301                             uri, values, null, null);
302         }
303 
304         /**
305          * Returns true iff the folder (message type) identifies an
306          * outgoing message.
307          */
isOutgoingFolder(int messageType)308         public static boolean isOutgoingFolder(int messageType) {
309             return  (messageType == MESSAGE_TYPE_FAILED)
310                     || (messageType == MESSAGE_TYPE_OUTBOX)
311                     || (messageType == MESSAGE_TYPE_SENT)
312                     || (messageType == MESSAGE_TYPE_QUEUED);
313         }
314 
315         /**
316          * Contains all text based SMS messages in the SMS app's inbox.
317          */
318         public static final class Inbox implements BaseColumns, TextBasedSmsColumns {
319             /**
320              * The content:// style URL for this table
321              */
322             public static final Uri CONTENT_URI =
323                 Uri.parse("content://sms/inbox");
324 
325             /**
326              * The default sort order for this table
327              */
328             public static final String DEFAULT_SORT_ORDER = "date DESC";
329 
330             /**
331              * Add an SMS to the Draft box.
332              *
333              * @param resolver the content resolver to use
334              * @param address the address of the sender
335              * @param body the body of the message
336              * @param subject the psuedo-subject of the message
337              * @param date the timestamp for the message
338              * @param read true if the message has been read, false if not
339              * @return the URI for the new message
340              */
addMessage(ContentResolver resolver, String address, String body, String subject, Long date, boolean read)341             public static Uri addMessage(ContentResolver resolver,
342                     String address, String body, String subject, Long date,
343                     boolean read) {
344                 return addMessageToUri(resolver, CONTENT_URI, address, body,
345                         subject, date, read, false);
346             }
347         }
348 
349         /**
350          * Contains all sent text based SMS messages in the SMS app's.
351          */
352         public static final class Sent implements BaseColumns, TextBasedSmsColumns {
353             /**
354              * The content:// style URL for this table
355              */
356             public static final Uri CONTENT_URI =
357                     Uri.parse("content://sms/sent");
358 
359             /**
360              * The default sort order for this table
361              */
362             public static final String DEFAULT_SORT_ORDER = "date DESC";
363 
364             /**
365              * Add an SMS to the Draft box.
366              *
367              * @param resolver the content resolver to use
368              * @param address the address of the sender
369              * @param body the body of the message
370              * @param subject the psuedo-subject of the message
371              * @param date the timestamp for the message
372              * @return the URI for the new message
373              */
addMessage(ContentResolver resolver, String address, String body, String subject, Long date)374             public static Uri addMessage(ContentResolver resolver,
375                     String address, String body, String subject, Long date) {
376                 return addMessageToUri(resolver, CONTENT_URI, address, body,
377                         subject, date, true, false);
378             }
379         }
380 
381         /**
382          * Contains all sent text based SMS messages in the SMS app's.
383          */
384         public static final class Draft implements BaseColumns, TextBasedSmsColumns {
385             /**
386              * The content:// style URL for this table
387              */
388             public static final Uri CONTENT_URI =
389                     Uri.parse("content://sms/draft");
390 
391             /**
392              * The default sort order for this table
393              */
394             public static final String DEFAULT_SORT_ORDER = "date DESC";
395 
396             /**
397              * Add an SMS to the Draft box.
398              *
399              * @param resolver the content resolver to use
400              * @param address the address of the sender
401              * @param body the body of the message
402              * @param subject the psuedo-subject of the message
403              * @param date the timestamp for the message
404              * @return the URI for the new message
405              */
addMessage(ContentResolver resolver, String address, String body, String subject, Long date)406             public static Uri addMessage(ContentResolver resolver,
407                     String address, String body, String subject, Long date) {
408                 return addMessageToUri(resolver, CONTENT_URI, address, body,
409                         subject, date, true, false);
410             }
411 
412             /**
413              * Save over an existing draft message.
414              *
415              * @param resolver the content resolver to use
416              * @param uri of existing message
417              * @param body the new body for the draft message
418              * @return true is successful, false otherwise
419              */
saveMessage(ContentResolver resolver, Uri uri, String body)420             public static boolean saveMessage(ContentResolver resolver,
421                     Uri uri, String body) {
422                 ContentValues values = new ContentValues(2);
423                 values.put(BODY, body);
424                 values.put(DATE, System.currentTimeMillis());
425                 return resolver.update(uri, values, null, null) == 1;
426             }
427         }
428 
429         /**
430          * Contains all pending outgoing text based SMS messages.
431          */
432         public static final class Outbox implements BaseColumns, TextBasedSmsColumns {
433             /**
434              * The content:// style URL for this table
435              */
436             public static final Uri CONTENT_URI =
437                 Uri.parse("content://sms/outbox");
438 
439             /**
440              * The default sort order for this table
441              */
442             public static final String DEFAULT_SORT_ORDER = "date DESC";
443 
444             /**
445              * Add an SMS to the Out box.
446              *
447              * @param resolver the content resolver to use
448              * @param address the address of the sender
449              * @param body the body of the message
450              * @param subject the psuedo-subject of the message
451              * @param date the timestamp for the message
452              * @param deliveryReport whether a delivery report was requested for the message
453              * @return the URI for the new message
454              */
addMessage(ContentResolver resolver, String address, String body, String subject, Long date, boolean deliveryReport, long threadId)455             public static Uri addMessage(ContentResolver resolver,
456                     String address, String body, String subject, Long date,
457                     boolean deliveryReport, long threadId) {
458                 return addMessageToUri(resolver, CONTENT_URI, address, body,
459                         subject, date, true, deliveryReport, threadId);
460             }
461         }
462 
463         /**
464          * Contains all sent text-based SMS messages in the SMS app's.
465          */
466         public static final class Conversations
467                 implements BaseColumns, TextBasedSmsColumns {
468             /**
469              * The content:// style URL for this table
470              */
471             public static final Uri CONTENT_URI =
472                 Uri.parse("content://sms/conversations");
473 
474             /**
475              * The default sort order for this table
476              */
477             public static final String DEFAULT_SORT_ORDER = "date DESC";
478 
479             /**
480              * The first 45 characters of the body of the message
481              * <P>Type: TEXT</P>
482              */
483             public static final String SNIPPET = "snippet";
484 
485             /**
486              * The number of messages in the conversation
487              * <P>Type: INTEGER</P>
488              */
489             public static final String MESSAGE_COUNT = "msg_count";
490         }
491 
492         /**
493          * Contains info about SMS related Intents that are broadcast.
494          */
495         public static final class Intents {
496             /**
497              * Set by BroadcastReceiver. Indicates the message was handled
498              * successfully.
499              */
500             public static final int RESULT_SMS_HANDLED = 1;
501 
502             /**
503              * Set by BroadcastReceiver. Indicates a generic error while
504              * processing the message.
505              */
506             public static final int RESULT_SMS_GENERIC_ERROR = 2;
507 
508             /**
509              * Set by BroadcastReceiver. Indicates insufficient memory to store
510              * the message.
511              */
512             public static final int RESULT_SMS_OUT_OF_MEMORY = 3;
513 
514             /**
515              * Set by BroadcastReceiver. Indicates the message, while
516              * possibly valid, is of a format or encoding that is not
517              * supported.
518              */
519             public static final int RESULT_SMS_UNSUPPORTED = 4;
520 
521             /**
522              * Broadcast Action: A new text based SMS message has been received
523              * by the device. The intent will have the following extra
524              * values:</p>
525              *
526              * <ul>
527              *   <li><em>pdus</em> - An Object[] od byte[]s containing the PDUs
528              *   that make up the message.</li>
529              * </ul>
530              *
531              * <p>The extra values can be extracted using
532              * {@link #getMessagesFromIntent(Intent)}.</p>
533              *
534              * <p>If a BroadcastReceiver encounters an error while processing
535              * this intent it should set the result code appropriately.</p>
536              */
537             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
538             public static final String SMS_RECEIVED_ACTION =
539                     "android.provider.Telephony.SMS_RECEIVED";
540 
541             /**
542              * Broadcast Action: A new data based SMS message has been received
543              * by the device. The intent will have the following extra
544              * values:</p>
545              *
546              * <ul>
547              *   <li><em>pdus</em> - An Object[] of byte[]s containing the PDUs
548              *   that make up the message.</li>
549              * </ul>
550              *
551              * <p>The extra values can be extracted using
552              * {@link #getMessagesFromIntent(Intent)}.</p>
553              *
554              * <p>If a BroadcastReceiver encounters an error while processing
555              * this intent it should set the result code appropriately.</p>
556              */
557             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
558             public static final String DATA_SMS_RECEIVED_ACTION =
559                     "android.intent.action.DATA_SMS_RECEIVED";
560 
561             /**
562              * Broadcast Action: A new WAP PUSH message has been received by the
563              * device. The intent will have the following extra
564              * values:</p>
565              *
566              * <ul>
567              *   <li><em>transactionId (Integer)</em> - The WAP transaction ID</li>
568              *   <li><em>pduType (Integer)</em> - The WAP PDU type</li>
569              *   <li><em>header (byte[])</em> - The header of the message</li>
570              *   <li><em>data (byte[])</em> - The data payload of the message</li>
571              *   <li><em>contentTypeParameters (HashMap&lt;String,String&gt;)</em>
572              *   - Any parameters associated with the content type
573              *   (decoded from the WSP Content-Type header)</li>
574              * </ul>
575              *
576              * <p>If a BroadcastReceiver encounters an error while processing
577              * this intent it should set the result code appropriately.</p>
578              *
579              * <p>The contentTypeParameters extra value is map of content parameters keyed by
580              * their names.</p>
581              *
582              * <p>If any unassigned well-known parameters are encountered, the key of the map will
583              * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter.  If
584              * a parameter has No-Value the value in the map will be null.</p>
585              */
586             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
587             public static final String WAP_PUSH_RECEIVED_ACTION =
588                     "android.provider.Telephony.WAP_PUSH_RECEIVED";
589 
590             /**
591              * Broadcast Action: A new Cell Broadcast message has been received
592              * by the device. The intent will have the following extra
593              * values:</p>
594              *
595              * <ul>
596              *   <li><em>message</em> - An SmsCbMessage object containing the broadcast message
597              *   data. This is not an emergency alert, so ETWS and CMAS data will be null.</li>
598              * </ul>
599              *
600              * <p>The extra values can be extracted using
601              * {@link #getMessagesFromIntent(Intent)}.</p>
602              *
603              * <p>If a BroadcastReceiver encounters an error while processing
604              * this intent it should set the result code appropriately.</p>
605              */
606             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
607             public static final String SMS_CB_RECEIVED_ACTION =
608                     "android.provider.Telephony.SMS_CB_RECEIVED";
609 
610             /**
611              * Broadcast Action: A new Emergency Broadcast message has been received
612              * by the device. The intent will have the following extra
613              * values:</p>
614              *
615              * <ul>
616              *   <li><em>message</em> - An SmsCbMessage object containing the broadcast message
617              *   data, including ETWS or CMAS warning notification info if present.</li>
618              * </ul>
619              *
620              * <p>The extra values can be extracted using
621              * {@link #getMessagesFromIntent(Intent)}.</p>
622              *
623              * <p>If a BroadcastReceiver encounters an error while processing
624              * this intent it should set the result code appropriately.</p>
625              */
626             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
627             public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
628                     "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
629 
630             /**
631              * Broadcast Action: A new CDMA SMS has been received containing Service Category
632              * Program Data (updates the list of enabled broadcast channels). The intent will
633              * have the following extra values:</p>
634              *
635              * <ul>
636              *   <li><em>operations</em> - An array of CdmaSmsCbProgramData objects containing
637              *   the service category operations (add/delete/clear) to perform.</li>
638              * </ul>
639              *
640              * <p>The extra values can be extracted using
641              * {@link #getMessagesFromIntent(Intent)}.</p>
642              *
643              * <p>If a BroadcastReceiver encounters an error while processing
644              * this intent it should set the result code appropriately.</p>
645              */
646             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
647             public static final String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION =
648                     "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
649 
650             /**
651              * Broadcast Action: The SIM storage for SMS messages is full.  If
652              * space is not freed, messages targeted for the SIM (class 2) may
653              * not be saved.
654              */
655             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
656             public static final String SIM_FULL_ACTION =
657                     "android.provider.Telephony.SIM_FULL";
658 
659             /**
660              * Broadcast Action: An incoming SMS has been rejected by the
661              * telephony framework.  This intent is sent in lieu of any
662              * of the RECEIVED_ACTION intents.  The intent will have the
663              * following extra value:</p>
664              *
665              * <ul>
666              *   <li><em>result</em> - An int result code, eg,
667              *   <code>{@link #RESULT_SMS_OUT_OF_MEMORY}</code>,
668              *   indicating the error returned to the network.</li>
669              * </ul>
670 
671              */
672             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
673             public static final String SMS_REJECTED_ACTION =
674                 "android.provider.Telephony.SMS_REJECTED";
675 
676             /**
677              * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
678              * {@link #DATA_SMS_RECEIVED_ACTION} intent.
679              *
680              * @param intent the intent to read from
681              * @return an array of SmsMessages for the PDUs
682              */
getMessagesFromIntent( Intent intent)683             public static SmsMessage[] getMessagesFromIntent(
684                     Intent intent) {
685                 Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
686                 String format = intent.getStringExtra("format");
687                 byte[][] pduObjs = new byte[messages.length][];
688 
689                 for (int i = 0; i < messages.length; i++) {
690                     pduObjs[i] = (byte[]) messages[i];
691                 }
692                 byte[][] pdus = new byte[pduObjs.length][];
693                 int pduCount = pdus.length;
694                 SmsMessage[] msgs = new SmsMessage[pduCount];
695                 for (int i = 0; i < pduCount; i++) {
696                     pdus[i] = pduObjs[i];
697                     msgs[i] = SmsMessage.createFromPdu(pdus[i], format);
698                 }
699                 return msgs;
700             }
701         }
702     }
703 
704     /**
705      * Base columns for tables that contain MMSs.
706      */
707     public interface BaseMmsColumns extends BaseColumns {
708 
709         public static final int MESSAGE_BOX_ALL    = 0;
710         public static final int MESSAGE_BOX_INBOX  = 1;
711         public static final int MESSAGE_BOX_SENT   = 2;
712         public static final int MESSAGE_BOX_DRAFTS = 3;
713         public static final int MESSAGE_BOX_OUTBOX = 4;
714 
715         /**
716          * The date the message was received.
717          * <P>Type: INTEGER (long)</P>
718          */
719         public static final String DATE = "date";
720 
721         /**
722          * The date the message was sent.
723          * <P>Type: INTEGER (long)</P>
724          */
725         public static final String DATE_SENT = "date_sent";
726 
727         /**
728          * The box which the message belong to, for example, MESSAGE_BOX_INBOX.
729          * <P>Type: INTEGER</P>
730          */
731         public static final String MESSAGE_BOX = "msg_box";
732 
733         /**
734          * Has the message been read.
735          * <P>Type: INTEGER (boolean)</P>
736          */
737         public static final String READ = "read";
738 
739         /**
740          * Indicates whether this message has been seen by the user. The "seen" flag will be
741          * used to figure out whether we need to throw up a statusbar notification or not.
742          */
743         public static final String SEEN = "seen";
744 
745         /**
746          * Indicates whether this message has only a text part (can also have a subject) and
747          * no picture, slideshow, or sound, etc., parts. The value is a boolean, 1 or 0.
748          */
749         public static final String TEXT_ONLY = "text_only";
750 
751         /**
752          * The Message-ID of the message.
753          * <P>Type: TEXT</P>
754          */
755         public static final String MESSAGE_ID = "m_id";
756 
757         /**
758          * The subject of the message, if present.
759          * <P>Type: TEXT</P>
760          */
761         public static final String SUBJECT = "sub";
762 
763         /**
764          * The character set of the subject, if present.
765          * <P>Type: INTEGER</P>
766          */
767         public static final String SUBJECT_CHARSET = "sub_cs";
768 
769         /**
770          * The Content-Type of the message.
771          * <P>Type: TEXT</P>
772          */
773         public static final String CONTENT_TYPE = "ct_t";
774 
775         /**
776          * The Content-Location of the message.
777          * <P>Type: TEXT</P>
778          */
779         public static final String CONTENT_LOCATION = "ct_l";
780 
781         /**
782          * The address of the sender.
783          * <P>Type: TEXT</P>
784          */
785         public static final String FROM = "from";
786 
787         /**
788          * The address of the recipients.
789          * <P>Type: TEXT</P>
790          */
791         public static final String TO = "to";
792 
793         /**
794          * The address of the cc. recipients.
795          * <P>Type: TEXT</P>
796          */
797         public static final String CC = "cc";
798 
799         /**
800          * The address of the bcc. recipients.
801          * <P>Type: TEXT</P>
802          */
803         public static final String BCC = "bcc";
804 
805         /**
806          * The expiry time of the message.
807          * <P>Type: INTEGER</P>
808          */
809         public static final String EXPIRY = "exp";
810 
811         /**
812          * The class of the message.
813          * <P>Type: TEXT</P>
814          */
815         public static final String MESSAGE_CLASS = "m_cls";
816 
817         /**
818          * The type of the message defined by MMS spec.
819          * <P>Type: INTEGER</P>
820          */
821         public static final String MESSAGE_TYPE = "m_type";
822 
823         /**
824          * The version of specification that this message conform.
825          * <P>Type: INTEGER</P>
826          */
827         public static final String MMS_VERSION = "v";
828 
829         /**
830          * The size of the message.
831          * <P>Type: INTEGER</P>
832          */
833         public static final String MESSAGE_SIZE = "m_size";
834 
835         /**
836          * The priority of the message.
837          * <P>Type: TEXT</P>
838          */
839         public static final String PRIORITY = "pri";
840 
841         /**
842          * The read-report of the message.
843          * <P>Type: TEXT</P>
844          */
845         public static final String READ_REPORT = "rr";
846 
847         /**
848          * Whether the report is allowed.
849          * <P>Type: TEXT</P>
850          */
851         public static final String REPORT_ALLOWED = "rpt_a";
852 
853         /**
854          * The response-status of the message.
855          * <P>Type: INTEGER</P>
856          */
857         public static final String RESPONSE_STATUS = "resp_st";
858 
859         /**
860          * The status of the message.
861          * <P>Type: INTEGER</P>
862          */
863         public static final String STATUS = "st";
864 
865         /**
866          * The transaction-id of the message.
867          * <P>Type: TEXT</P>
868          */
869         public static final String TRANSACTION_ID = "tr_id";
870 
871         /**
872          * The retrieve-status of the message.
873          * <P>Type: INTEGER</P>
874          */
875         public static final String RETRIEVE_STATUS = "retr_st";
876 
877         /**
878          * The retrieve-text of the message.
879          * <P>Type: TEXT</P>
880          */
881         public static final String RETRIEVE_TEXT = "retr_txt";
882 
883         /**
884          * The character set of the retrieve-text.
885          * <P>Type: TEXT</P>
886          */
887         public static final String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
888 
889         /**
890          * The read-status of the message.
891          * <P>Type: INTEGER</P>
892          */
893         public static final String READ_STATUS = "read_status";
894 
895         /**
896          * The content-class of the message.
897          * <P>Type: INTEGER</P>
898          */
899         public static final String CONTENT_CLASS = "ct_cls";
900 
901         /**
902          * The delivery-report of the message.
903          * <P>Type: INTEGER</P>
904          */
905         public static final String DELIVERY_REPORT = "d_rpt";
906 
907         /**
908          * The delivery-time-token of the message.
909          * <P>Type: INTEGER</P>
910          */
911         public static final String DELIVERY_TIME_TOKEN = "d_tm_tok";
912 
913         /**
914          * The delivery-time of the message.
915          * <P>Type: INTEGER</P>
916          */
917         public static final String DELIVERY_TIME = "d_tm";
918 
919         /**
920          * The response-text of the message.
921          * <P>Type: TEXT</P>
922          */
923         public static final String RESPONSE_TEXT = "resp_txt";
924 
925         /**
926          * The sender-visibility of the message.
927          * <P>Type: TEXT</P>
928          */
929         public static final String SENDER_VISIBILITY = "s_vis";
930 
931         /**
932          * The reply-charging of the message.
933          * <P>Type: INTEGER</P>
934          */
935         public static final String REPLY_CHARGING = "r_chg";
936 
937         /**
938          * The reply-charging-deadline-token of the message.
939          * <P>Type: INTEGER</P>
940          */
941         public static final String REPLY_CHARGING_DEADLINE_TOKEN = "r_chg_dl_tok";
942 
943         /**
944          * The reply-charging-deadline of the message.
945          * <P>Type: INTEGER</P>
946          */
947         public static final String REPLY_CHARGING_DEADLINE = "r_chg_dl";
948 
949         /**
950          * The reply-charging-id of the message.
951          * <P>Type: TEXT</P>
952          */
953         public static final String REPLY_CHARGING_ID = "r_chg_id";
954 
955         /**
956          * The reply-charging-size of the message.
957          * <P>Type: INTEGER</P>
958          */
959         public static final String REPLY_CHARGING_SIZE = "r_chg_sz";
960 
961         /**
962          * The previously-sent-by of the message.
963          * <P>Type: TEXT</P>
964          */
965         public static final String PREVIOUSLY_SENT_BY = "p_s_by";
966 
967         /**
968          * The previously-sent-date of the message.
969          * <P>Type: INTEGER</P>
970          */
971         public static final String PREVIOUSLY_SENT_DATE = "p_s_d";
972 
973         /**
974          * The store of the message.
975          * <P>Type: TEXT</P>
976          */
977         public static final String STORE = "store";
978 
979         /**
980          * The mm-state of the message.
981          * <P>Type: INTEGER</P>
982          */
983         public static final String MM_STATE = "mm_st";
984 
985         /**
986          * The mm-flags-token of the message.
987          * <P>Type: INTEGER</P>
988          */
989         public static final String MM_FLAGS_TOKEN = "mm_flg_tok";
990 
991         /**
992          * The mm-flags of the message.
993          * <P>Type: TEXT</P>
994          */
995         public static final String MM_FLAGS = "mm_flg";
996 
997         /**
998          * The store-status of the message.
999          * <P>Type: TEXT</P>
1000          */
1001         public static final String STORE_STATUS = "store_st";
1002 
1003         /**
1004          * The store-status-text of the message.
1005          * <P>Type: TEXT</P>
1006          */
1007         public static final String STORE_STATUS_TEXT = "store_st_txt";
1008 
1009         /**
1010          * The stored of the message.
1011          * <P>Type: TEXT</P>
1012          */
1013         public static final String STORED = "stored";
1014 
1015         /**
1016          * The totals of the message.
1017          * <P>Type: TEXT</P>
1018          */
1019         public static final String TOTALS = "totals";
1020 
1021         /**
1022          * The mbox-totals of the message.
1023          * <P>Type: TEXT</P>
1024          */
1025         public static final String MBOX_TOTALS = "mb_t";
1026 
1027         /**
1028          * The mbox-totals-token of the message.
1029          * <P>Type: INTEGER</P>
1030          */
1031         public static final String MBOX_TOTALS_TOKEN = "mb_t_tok";
1032 
1033         /**
1034          * The quotas of the message.
1035          * <P>Type: TEXT</P>
1036          */
1037         public static final String QUOTAS = "qt";
1038 
1039         /**
1040          * The mbox-quotas of the message.
1041          * <P>Type: TEXT</P>
1042          */
1043         public static final String MBOX_QUOTAS = "mb_qt";
1044 
1045         /**
1046          * The mbox-quotas-token of the message.
1047          * <P>Type: INTEGER</P>
1048          */
1049         public static final String MBOX_QUOTAS_TOKEN = "mb_qt_tok";
1050 
1051         /**
1052          * The message-count of the message.
1053          * <P>Type: INTEGER</P>
1054          */
1055         public static final String MESSAGE_COUNT = "m_cnt";
1056 
1057         /**
1058          * The start of the message.
1059          * <P>Type: INTEGER</P>
1060          */
1061         public static final String START = "start";
1062 
1063         /**
1064          * The distribution-indicator of the message.
1065          * <P>Type: TEXT</P>
1066          */
1067         public static final String DISTRIBUTION_INDICATOR = "d_ind";
1068 
1069         /**
1070          * The element-descriptor of the message.
1071          * <P>Type: TEXT</P>
1072          */
1073         public static final String ELEMENT_DESCRIPTOR = "e_des";
1074 
1075         /**
1076          * The limit of the message.
1077          * <P>Type: INTEGER</P>
1078          */
1079         public static final String LIMIT = "limit";
1080 
1081         /**
1082          * The recommended-retrieval-mode of the message.
1083          * <P>Type: INTEGER</P>
1084          */
1085         public static final String RECOMMENDED_RETRIEVAL_MODE = "r_r_mod";
1086 
1087         /**
1088          * The recommended-retrieval-mode-text of the message.
1089          * <P>Type: TEXT</P>
1090          */
1091         public static final String RECOMMENDED_RETRIEVAL_MODE_TEXT = "r_r_mod_txt";
1092 
1093         /**
1094          * The status-text of the message.
1095          * <P>Type: TEXT</P>
1096          */
1097         public static final String STATUS_TEXT = "st_txt";
1098 
1099         /**
1100          * The applic-id of the message.
1101          * <P>Type: TEXT</P>
1102          */
1103         public static final String APPLIC_ID = "apl_id";
1104 
1105         /**
1106          * The reply-applic-id of the message.
1107          * <P>Type: TEXT</P>
1108          */
1109         public static final String REPLY_APPLIC_ID = "r_apl_id";
1110 
1111         /**
1112          * The aux-applic-id of the message.
1113          * <P>Type: TEXT</P>
1114          */
1115         public static final String AUX_APPLIC_ID = "aux_apl_id";
1116 
1117         /**
1118          * The drm-content of the message.
1119          * <P>Type: TEXT</P>
1120          */
1121         public static final String DRM_CONTENT = "drm_c";
1122 
1123         /**
1124          * The adaptation-allowed of the message.
1125          * <P>Type: TEXT</P>
1126          */
1127         public static final String ADAPTATION_ALLOWED = "adp_a";
1128 
1129         /**
1130          * The replace-id of the message.
1131          * <P>Type: TEXT</P>
1132          */
1133         public static final String REPLACE_ID = "repl_id";
1134 
1135         /**
1136          * The cancel-id of the message.
1137          * <P>Type: TEXT</P>
1138          */
1139         public static final String CANCEL_ID = "cl_id";
1140 
1141         /**
1142          * The cancel-status of the message.
1143          * <P>Type: INTEGER</P>
1144          */
1145         public static final String CANCEL_STATUS = "cl_st";
1146 
1147         /**
1148          * The thread ID of the message
1149          * <P>Type: INTEGER</P>
1150          */
1151         public static final String THREAD_ID = "thread_id";
1152 
1153         /**
1154          * Has the message been locked?
1155          * <P>Type: INTEGER (boolean)</P>
1156          */
1157         public static final String LOCKED = "locked";
1158 
1159         /**
1160          * Meta data used externally.
1161          * <P>Type: TEXT</P>
1162          */
1163         public static final String META_DATA = "meta_data";
1164     }
1165 
1166     /**
1167      * Columns for the "canonical_addresses" table used by MMS and
1168      * SMS."
1169      */
1170     public interface CanonicalAddressesColumns extends BaseColumns {
1171         /**
1172          * An address used in MMS or SMS.  Email addresses are
1173          * converted to lower case and are compared by string
1174          * equality.  Other addresses are compared using
1175          * PHONE_NUMBERS_EQUAL.
1176          * <P>Type: TEXT</P>
1177          */
1178         public static final String ADDRESS = "address";
1179     }
1180 
1181     /**
1182      * Columns for the "threads" table used by MMS and SMS.
1183      */
1184     public interface ThreadsColumns extends BaseColumns {
1185         /**
1186          * The date at which the thread was created.
1187          *
1188          * <P>Type: INTEGER (long)</P>
1189          */
1190         public static final String DATE = "date";
1191 
1192         /**
1193          * A string encoding of the recipient IDs of the recipients of
1194          * the message, in numerical order and separated by spaces.
1195          * <P>Type: TEXT</P>
1196          */
1197         public static final String RECIPIENT_IDS = "recipient_ids";
1198 
1199         /**
1200          * The message count of the thread.
1201          * <P>Type: INTEGER</P>
1202          */
1203         public static final String MESSAGE_COUNT = "message_count";
1204         /**
1205          * Indicates whether all messages of the thread have been read.
1206          * <P>Type: INTEGER</P>
1207          */
1208         public static final String READ = "read";
1209 
1210         /**
1211          * The snippet of the latest message in the thread.
1212          * <P>Type: TEXT</P>
1213          */
1214         public static final String SNIPPET = "snippet";
1215         /**
1216          * The charset of the snippet.
1217          * <P>Type: INTEGER</P>
1218          */
1219         public static final String SNIPPET_CHARSET = "snippet_cs";
1220         /**
1221          * Type of the thread, either Threads.COMMON_THREAD or
1222          * Threads.BROADCAST_THREAD.
1223          * <P>Type: INTEGER</P>
1224          */
1225         public static final String TYPE = "type";
1226         /**
1227          * Indicates whether there is a transmission error in the thread.
1228          * <P>Type: INTEGER</P>
1229          */
1230         public static final String ERROR = "error";
1231         /**
1232          * Indicates whether this thread contains any attachments.
1233          * <P>Type: INTEGER</P>
1234          */
1235         public static final String HAS_ATTACHMENT = "has_attachment";
1236     }
1237 
1238     /**
1239      * Helper functions for the "threads" table used by MMS and SMS.
1240      */
1241     public static final class Threads implements ThreadsColumns {
1242         private static final String[] ID_PROJECTION = { BaseColumns._ID };
1243         private static final Uri THREAD_ID_CONTENT_URI = Uri.parse(
1244                 "content://mms-sms/threadID");
1245         public static final Uri CONTENT_URI = Uri.withAppendedPath(
1246                 MmsSms.CONTENT_URI, "conversations");
1247         public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(
1248                 CONTENT_URI, "obsolete");
1249 
1250         public static final int COMMON_THREAD    = 0;
1251         public static final int BROADCAST_THREAD = 1;
1252 
1253         // No one should construct an instance of this class.
Threads()1254         private Threads() {
1255         }
1256 
1257         /**
1258          * This is a single-recipient version of
1259          * getOrCreateThreadId.  It's convenient for use with SMS
1260          * messages.
1261          */
getOrCreateThreadId(Context context, String recipient)1262         public static long getOrCreateThreadId(Context context, String recipient) {
1263             Set<String> recipients = new HashSet<String>();
1264 
1265             recipients.add(recipient);
1266             return getOrCreateThreadId(context, recipients);
1267         }
1268 
1269         /**
1270          * Given the recipients list and subject of an unsaved message,
1271          * return its thread ID.  If the message starts a new thread,
1272          * allocate a new thread ID.  Otherwise, use the appropriate
1273          * existing thread ID.
1274          *
1275          * Find the thread ID of the same set of recipients (in
1276          * any order, without any additions). If one
1277          * is found, return it.  Otherwise, return a unique thread ID.
1278          */
getOrCreateThreadId( Context context, Set<String> recipients)1279         public static long getOrCreateThreadId(
1280                 Context context, Set<String> recipients) {
1281             Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();
1282 
1283             for (String recipient : recipients) {
1284                 if (Mms.isEmailAddress(recipient)) {
1285                     recipient = Mms.extractAddrSpec(recipient);
1286                 }
1287 
1288                 uriBuilder.appendQueryParameter("recipient", recipient);
1289             }
1290 
1291             Uri uri = uriBuilder.build();
1292             //if (DEBUG) Rlog.v(TAG, "getOrCreateThreadId uri: " + uri);
1293 
1294             Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
1295                     uri, ID_PROJECTION, null, null, null);
1296             if (cursor != null) {
1297                 try {
1298                     if (cursor.moveToFirst()) {
1299                         return cursor.getLong(0);
1300                     } else {
1301                         Rlog.e(TAG, "getOrCreateThreadId returned no rows!");
1302                     }
1303                 } finally {
1304                     cursor.close();
1305                 }
1306             }
1307 
1308             Rlog.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString());
1309             throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
1310         }
1311     }
1312 
1313     /**
1314      * Contains all MMS messages.
1315      */
1316     public static final class Mms implements BaseMmsColumns {
1317         /**
1318          * The content:// style URL for this table
1319          */
1320         public static final Uri CONTENT_URI = Uri.parse("content://mms");
1321 
1322         public static final Uri REPORT_REQUEST_URI = Uri.withAppendedPath(
1323                                             CONTENT_URI, "report-request");
1324 
1325         public static final Uri REPORT_STATUS_URI = Uri.withAppendedPath(
1326                                             CONTENT_URI, "report-status");
1327 
1328         /**
1329          * The default sort order for this table
1330          */
1331         public static final String DEFAULT_SORT_ORDER = "date DESC";
1332 
1333         /**
1334          * mailbox         =       name-addr
1335          * name-addr       =       [display-name] angle-addr
1336          * angle-addr      =       [CFWS] "<" addr-spec ">" [CFWS]
1337          */
1338         public static final Pattern NAME_ADDR_EMAIL_PATTERN =
1339                 Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");
1340 
1341         /**
1342          * quoted-string   =       [CFWS]
1343          *                         DQUOTE *([FWS] qcontent) [FWS] DQUOTE
1344          *                         [CFWS]
1345          */
1346         public static final Pattern QUOTED_STRING_PATTERN =
1347                 Pattern.compile("\\s*\"([^\"]*)\"\\s*");
1348 
query( ContentResolver cr, String[] projection)1349         public static final Cursor query(
1350                 ContentResolver cr, String[] projection) {
1351             return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
1352         }
1353 
query( ContentResolver cr, String[] projection, String where, String orderBy)1354         public static final Cursor query(
1355                 ContentResolver cr, String[] projection,
1356                 String where, String orderBy) {
1357             return cr.query(CONTENT_URI, projection,
1358                     where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
1359         }
1360 
getMessageBoxName(int msgBox)1361         public static final String getMessageBoxName(int msgBox) {
1362             switch (msgBox) {
1363                 case MESSAGE_BOX_ALL:
1364                     return "all";
1365                 case MESSAGE_BOX_INBOX:
1366                     return "inbox";
1367                 case MESSAGE_BOX_SENT:
1368                     return "sent";
1369                 case MESSAGE_BOX_DRAFTS:
1370                     return "drafts";
1371                 case MESSAGE_BOX_OUTBOX:
1372                     return "outbox";
1373                 default:
1374                     throw new IllegalArgumentException("Invalid message box: " + msgBox);
1375             }
1376         }
1377 
extractAddrSpec(String address)1378         public static String extractAddrSpec(String address) {
1379             Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);
1380 
1381             if (match.matches()) {
1382                 return match.group(2);
1383             }
1384             return address;
1385         }
1386 
1387         /**
1388          * Returns true if the address is an email address
1389          *
1390          * @param address the input address to be tested
1391          * @return true if address is an email address
1392          */
isEmailAddress(String address)1393         public static boolean isEmailAddress(String address) {
1394             if (TextUtils.isEmpty(address)) {
1395                 return false;
1396             }
1397 
1398             String s = extractAddrSpec(address);
1399             Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
1400             return match.matches();
1401         }
1402 
1403         /**
1404          * Returns true if the number is a Phone number
1405          *
1406          * @param number the input number to be tested
1407          * @return true if number is a Phone number
1408          */
isPhoneNumber(String number)1409         public static boolean isPhoneNumber(String number) {
1410             if (TextUtils.isEmpty(number)) {
1411                 return false;
1412             }
1413 
1414             Matcher match = Patterns.PHONE.matcher(number);
1415             return match.matches();
1416         }
1417 
1418         /**
1419          * Contains all MMS messages in the MMS app's inbox.
1420          */
1421         public static final class Inbox implements BaseMmsColumns {
1422             /**
1423              * The content:// style URL for this table
1424              */
1425             public static final Uri
1426                     CONTENT_URI = Uri.parse("content://mms/inbox");
1427 
1428             /**
1429              * The default sort order for this table
1430              */
1431             public static final String DEFAULT_SORT_ORDER = "date DESC";
1432         }
1433 
1434         /**
1435          * Contains all MMS messages in the MMS app's sent box.
1436          */
1437         public static final class Sent implements BaseMmsColumns {
1438             /**
1439              * The content:// style URL for this table
1440              */
1441             public static final Uri
1442                     CONTENT_URI = Uri.parse("content://mms/sent");
1443 
1444             /**
1445              * The default sort order for this table
1446              */
1447             public static final String DEFAULT_SORT_ORDER = "date DESC";
1448         }
1449 
1450         /**
1451          * Contains all MMS messages in the MMS app's drafts box.
1452          */
1453         public static final class Draft implements BaseMmsColumns {
1454             /**
1455              * The content:// style URL for this table
1456              */
1457             public static final Uri
1458                     CONTENT_URI = Uri.parse("content://mms/drafts");
1459 
1460             /**
1461              * The default sort order for this table
1462              */
1463             public static final String DEFAULT_SORT_ORDER = "date DESC";
1464         }
1465 
1466         /**
1467          * Contains all MMS messages in the MMS app's outbox.
1468          */
1469         public static final class Outbox implements BaseMmsColumns {
1470             /**
1471              * The content:// style URL for this table
1472              */
1473             public static final Uri
1474                     CONTENT_URI = Uri.parse("content://mms/outbox");
1475 
1476             /**
1477              * The default sort order for this table
1478              */
1479             public static final String DEFAULT_SORT_ORDER = "date DESC";
1480         }
1481 
1482         public static final class Addr implements BaseColumns {
1483             /**
1484              * The ID of MM which this address entry belongs to.
1485              */
1486             public static final String MSG_ID = "msg_id";
1487 
1488             /**
1489              * The ID of contact entry in Phone Book.
1490              */
1491             public static final String CONTACT_ID = "contact_id";
1492 
1493             /**
1494              * The address text.
1495              */
1496             public static final String ADDRESS = "address";
1497 
1498             /**
1499              * Type of address, must be one of PduHeaders.BCC,
1500              * PduHeaders.CC, PduHeaders.FROM, PduHeaders.TO.
1501              */
1502             public static final String TYPE = "type";
1503 
1504             /**
1505              * Character set of this entry.
1506              */
1507             public static final String CHARSET = "charset";
1508         }
1509 
1510         public static final class Part implements BaseColumns {
1511             /**
1512              * The identifier of the message which this part belongs to.
1513              * <P>Type: INTEGER</P>
1514              */
1515             public static final String MSG_ID = "mid";
1516 
1517             /**
1518              * The order of the part.
1519              * <P>Type: INTEGER</P>
1520              */
1521             public static final String SEQ = "seq";
1522 
1523             /**
1524              * The content type of the part.
1525              * <P>Type: TEXT</P>
1526              */
1527             public static final String CONTENT_TYPE = "ct";
1528 
1529             /**
1530              * The name of the part.
1531              * <P>Type: TEXT</P>
1532              */
1533             public static final String NAME = "name";
1534 
1535             /**
1536              * The charset of the part.
1537              * <P>Type: TEXT</P>
1538              */
1539             public static final String CHARSET = "chset";
1540 
1541             /**
1542              * The file name of the part.
1543              * <P>Type: TEXT</P>
1544              */
1545             public static final String FILENAME = "fn";
1546 
1547             /**
1548              * The content disposition of the part.
1549              * <P>Type: TEXT</P>
1550              */
1551             public static final String CONTENT_DISPOSITION = "cd";
1552 
1553             /**
1554              * The content ID of the part.
1555              * <P>Type: INTEGER</P>
1556              */
1557             public static final String CONTENT_ID = "cid";
1558 
1559             /**
1560              * The content location of the part.
1561              * <P>Type: INTEGER</P>
1562              */
1563             public static final String CONTENT_LOCATION = "cl";
1564 
1565             /**
1566              * The start of content-type of the message.
1567              * <P>Type: INTEGER</P>
1568              */
1569             public static final String CT_START = "ctt_s";
1570 
1571             /**
1572              * The type of content-type of the message.
1573              * <P>Type: TEXT</P>
1574              */
1575             public static final String CT_TYPE = "ctt_t";
1576 
1577             /**
1578              * The location(on filesystem) of the binary data of the part.
1579              * <P>Type: INTEGER</P>
1580              */
1581             public static final String _DATA = "_data";
1582 
1583             public static final String TEXT = "text";
1584 
1585         }
1586 
1587         public static final class Rate {
1588             public static final Uri CONTENT_URI = Uri.withAppendedPath(
1589                     Mms.CONTENT_URI, "rate");
1590             /**
1591              * When a message was successfully sent.
1592              * <P>Type: INTEGER</P>
1593              */
1594             public static final String SENT_TIME = "sent_time";
1595         }
1596 
1597         public static final class Intents {
Intents()1598             private Intents() {
1599                 // Non-instantiatable.
1600             }
1601 
1602             /**
1603              * The extra field to store the contents of the Intent,
1604              * which should be an array of Uri.
1605              */
1606             public static final String EXTRA_CONTENTS = "contents";
1607             /**
1608              * The extra field to store the type of the contents,
1609              * which should be an array of String.
1610              */
1611             public static final String EXTRA_TYPES    = "types";
1612             /**
1613              * The extra field to store the 'Cc' addresses.
1614              */
1615             public static final String EXTRA_CC       = "cc";
1616             /**
1617              * The extra field to store the 'Bcc' addresses;
1618              */
1619             public static final String EXTRA_BCC      = "bcc";
1620             /**
1621              * The extra field to store the 'Subject'.
1622              */
1623             public static final String EXTRA_SUBJECT  = "subject";
1624             /**
1625              * Indicates that the contents of specified URIs were changed.
1626              * The application which is showing or caching these contents
1627              * should be updated.
1628              */
1629             public static final String
1630             CONTENT_CHANGED_ACTION = "android.intent.action.CONTENT_CHANGED";
1631             /**
1632              * An extra field which stores the URI of deleted contents.
1633              */
1634             public static final String DELETED_CONTENTS = "deleted_contents";
1635         }
1636     }
1637 
1638     /**
1639      * Contains all MMS and SMS messages.
1640      */
1641     public static final class MmsSms implements BaseColumns {
1642         /**
1643          * The column to distinguish SMS &amp; MMS messages in query results.
1644          */
1645         public static final String TYPE_DISCRIMINATOR_COLUMN =
1646                 "transport_type";
1647 
1648         public static final Uri CONTENT_URI = Uri.parse("content://mms-sms/");
1649 
1650         public static final Uri CONTENT_CONVERSATIONS_URI = Uri.parse(
1651                 "content://mms-sms/conversations");
1652 
1653         public static final Uri CONTENT_FILTER_BYPHONE_URI = Uri.parse(
1654                 "content://mms-sms/messages/byphone");
1655 
1656         public static final Uri CONTENT_UNDELIVERED_URI = Uri.parse(
1657                 "content://mms-sms/undelivered");
1658 
1659         public static final Uri CONTENT_DRAFT_URI = Uri.parse(
1660                 "content://mms-sms/draft");
1661 
1662         public static final Uri CONTENT_LOCKED_URI = Uri.parse(
1663                 "content://mms-sms/locked");
1664 
1665         /***
1666          * Pass in a query parameter called "pattern" which is the text
1667          * to search for.
1668          * The sort order is fixed to be thread_id ASC,date DESC.
1669          */
1670         public static final Uri SEARCH_URI = Uri.parse(
1671                 "content://mms-sms/search");
1672 
1673         // Constants for message protocol types.
1674         public static final int SMS_PROTO = 0;
1675         public static final int MMS_PROTO = 1;
1676 
1677         // Constants for error types of pending messages.
1678         public static final int NO_ERROR                      = 0;
1679         public static final int ERR_TYPE_GENERIC              = 1;
1680         public static final int ERR_TYPE_SMS_PROTO_TRANSIENT  = 2;
1681         public static final int ERR_TYPE_MMS_PROTO_TRANSIENT  = 3;
1682         public static final int ERR_TYPE_TRANSPORT_FAILURE    = 4;
1683         public static final int ERR_TYPE_GENERIC_PERMANENT    = 10;
1684         public static final int ERR_TYPE_SMS_PROTO_PERMANENT  = 11;
1685         public static final int ERR_TYPE_MMS_PROTO_PERMANENT  = 12;
1686 
1687         public static final class PendingMessages implements BaseColumns {
1688             public static final Uri CONTENT_URI = Uri.withAppendedPath(
1689                     MmsSms.CONTENT_URI, "pending");
1690             /**
1691              * The type of transport protocol(MMS or SMS).
1692              * <P>Type: INTEGER</P>
1693              */
1694             public static final String PROTO_TYPE = "proto_type";
1695             /**
1696              * The ID of the message to be sent or downloaded.
1697              * <P>Type: INTEGER</P>
1698              */
1699             public static final String MSG_ID = "msg_id";
1700             /**
1701              * The type of the message to be sent or downloaded.
1702              * This field is only valid for MM. For SM, its value is always
1703              * set to 0.
1704              */
1705             public static final String MSG_TYPE = "msg_type";
1706             /**
1707              * The type of the error code.
1708              * <P>Type: INTEGER</P>
1709              */
1710             public static final String ERROR_TYPE = "err_type";
1711             /**
1712              * The error code of sending/retrieving process.
1713              * <P>Type:  INTEGER</P>
1714              */
1715             public static final String ERROR_CODE = "err_code";
1716             /**
1717              * How many times we tried to send or download the message.
1718              * <P>Type:  INTEGER</P>
1719              */
1720             public static final String RETRY_INDEX = "retry_index";
1721             /**
1722              * The time to do next retry.
1723              */
1724             public static final String DUE_TIME = "due_time";
1725             /**
1726              * The time we last tried to send or download the message.
1727              */
1728             public static final String LAST_TRY = "last_try";
1729         }
1730 
1731         public static final class WordsTable {
1732             public static final String ID = "_id";
1733             public static final String SOURCE_ROW_ID = "source_id";
1734             public static final String TABLE_ID = "table_to_use";
1735             public static final String INDEXED_TEXT = "index_text";
1736         }
1737     }
1738 
1739     public static final class Carriers implements BaseColumns {
1740         /**
1741          * The content:// style URL for this table
1742          */
1743         public static final Uri CONTENT_URI =
1744             Uri.parse("content://telephony/carriers");
1745 
1746         /**
1747          * The default sort order for this table
1748          */
1749         public static final String DEFAULT_SORT_ORDER = "name ASC";
1750 
1751         public static final String NAME = "name";
1752 
1753         public static final String APN = "apn";
1754 
1755         public static final String PROXY = "proxy";
1756 
1757         public static final String PORT = "port";
1758 
1759         public static final String MMSPROXY = "mmsproxy";
1760 
1761         public static final String MMSPORT = "mmsport";
1762 
1763         public static final String SERVER = "server";
1764 
1765         public static final String USER = "user";
1766 
1767         public static final String PASSWORD = "password";
1768 
1769         public static final String MMSC = "mmsc";
1770 
1771         public static final String MCC = "mcc";
1772 
1773         public static final String MNC = "mnc";
1774 
1775         public static final String NUMERIC = "numeric";
1776 
1777         public static final String AUTH_TYPE = "authtype";
1778 
1779         public static final String TYPE = "type";
1780 
1781         public static final String INACTIVE_TIMER = "inactivetimer";
1782 
1783         // Only if enabled try Data Connection.
1784         public static final String ENABLED = "enabled";
1785 
1786         // Rules apply based on class.
1787         public static final String CLASS = "class";
1788 
1789         /**
1790          * The protocol to be used to connect to this APN.
1791          *
1792          * One of the PDP_type values in TS 27.007 section 10.1.1.
1793          * For example, "IP", "IPV6", "IPV4V6", or "PPP".
1794          */
1795         public static final String PROTOCOL = "protocol";
1796 
1797         /**
1798           * The protocol to be used to connect to this APN when roaming.
1799           *
1800           * The syntax is the same as protocol.
1801           */
1802         public static final String ROAMING_PROTOCOL = "roaming_protocol";
1803 
1804         public static final String CURRENT = "current";
1805 
1806         /**
1807           * Current status of APN
1808           * true : enabled APN, false : disabled APN.
1809           */
1810         public static final String CARRIER_ENABLED = "carrier_enabled";
1811 
1812         /**
1813           * Radio Access Technology info
1814           * To check what values can hold, refer to ServiceState.java.
1815           * This should be spread to other technologies,
1816           * but currently only used for LTE(14) and EHRPD(13).
1817           */
1818         public static final String BEARER = "bearer";
1819 
1820         /**
1821           * MVNO type
1822           * spn(Service Provider Name), imsi, gid(Group Identifier Level 1)
1823           */
1824         public static final String MVNO_TYPE = "mvno_type";
1825 
1826         /**
1827           * MVNO data
1828           * Use the following examples.
1829           * spn: A MOBILE, BEN NL, ...
1830           * imsi: 302720x94, 2060188, ...
1831           * gid: 4E, 33, ...
1832           */
1833         public static final String MVNO_MATCH_DATA = "mvno_match_data";
1834     }
1835 
1836     /**
1837      * Contains received SMS cell broadcast messages.
1838      */
1839     public static final class CellBroadcasts implements BaseColumns {
1840 
1841         /** Not instantiable. */
CellBroadcasts()1842         private CellBroadcasts() {}
1843 
1844         /**
1845          * The content:// style URL for this table
1846          */
1847         public static final Uri CONTENT_URI =
1848             Uri.parse("content://cellbroadcasts");
1849 
1850         /**
1851          * Message geographical scope.
1852          * <P>Type: INTEGER</P>
1853          */
1854         public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
1855 
1856         /**
1857          * Message serial number.
1858          * <P>Type: INTEGER</P>
1859          */
1860         public static final String SERIAL_NUMBER = "serial_number";
1861 
1862         /**
1863          * PLMN of broadcast sender. (SERIAL_NUMBER + PLMN + LAC + CID) uniquely identifies a
1864          * broadcast for duplicate detection purposes.
1865          * <P>Type: TEXT</P>
1866          */
1867         public static final String PLMN = "plmn";
1868 
1869         /**
1870          * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA.
1871          * Only included if Geographical Scope of message is not PLMN wide (01).
1872          * <P>Type: INTEGER</P>
1873          */
1874         public static final String LAC = "lac";
1875 
1876         /**
1877          * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the
1878          * Geographical Scope of message is cell wide (00 or 11).
1879          * <P>Type: INTEGER</P>
1880          */
1881         public static final String CID = "cid";
1882 
1883         /**
1884          * Message code (OBSOLETE: merged into SERIAL_NUMBER).
1885          * <P>Type: INTEGER</P>
1886          */
1887         public static final String V1_MESSAGE_CODE = "message_code";
1888 
1889         /**
1890          * Message identifier (OBSOLETE: renamed to SERVICE_CATEGORY).
1891          * <P>Type: INTEGER</P>
1892          */
1893         public static final String V1_MESSAGE_IDENTIFIER = "message_id";
1894 
1895         /**
1896          * Service category (GSM/UMTS message identifier, CDMA service category).
1897          * <P>Type: INTEGER</P>
1898          */
1899         public static final String SERVICE_CATEGORY = "service_category";
1900 
1901         /**
1902          * Message language code.
1903          * <P>Type: TEXT</P>
1904          */
1905         public static final String LANGUAGE_CODE = "language";
1906 
1907         /**
1908          * Message body.
1909          * <P>Type: TEXT</P>
1910          */
1911         public static final String MESSAGE_BODY = "body";
1912 
1913         /**
1914          * Message delivery time.
1915          * <P>Type: INTEGER (long)</P>
1916          */
1917         public static final String DELIVERY_TIME = "date";
1918 
1919         /**
1920          * Has the message been viewed?
1921          * <P>Type: INTEGER (boolean)</P>
1922          */
1923         public static final String MESSAGE_READ = "read";
1924 
1925         /**
1926          * Message format (3GPP or 3GPP2).
1927          * <P>Type: INTEGER</P>
1928          */
1929         public static final String MESSAGE_FORMAT = "format";
1930 
1931         /**
1932          * Message priority (including emergency).
1933          * <P>Type: INTEGER</P>
1934          */
1935         public static final String MESSAGE_PRIORITY = "priority";
1936 
1937         /**
1938          * ETWS warning type (ETWS alerts only).
1939          * <P>Type: INTEGER</P>
1940          */
1941         public static final String ETWS_WARNING_TYPE = "etws_warning_type";
1942 
1943         /**
1944          * CMAS message class (CMAS alerts only).
1945          * <P>Type: INTEGER</P>
1946          */
1947         public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
1948 
1949         /**
1950          * CMAS category (CMAS alerts only).
1951          * <P>Type: INTEGER</P>
1952          */
1953         public static final String CMAS_CATEGORY = "cmas_category";
1954 
1955         /**
1956          * CMAS response type (CMAS alerts only).
1957          * <P>Type: INTEGER</P>
1958          */
1959         public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
1960 
1961         /**
1962          * CMAS severity (CMAS alerts only).
1963          * <P>Type: INTEGER</P>
1964          */
1965         public static final String CMAS_SEVERITY = "cmas_severity";
1966 
1967         /**
1968          * CMAS urgency (CMAS alerts only).
1969          * <P>Type: INTEGER</P>
1970          */
1971         public static final String CMAS_URGENCY = "cmas_urgency";
1972 
1973         /**
1974          * CMAS certainty (CMAS alerts only).
1975          * <P>Type: INTEGER</P>
1976          */
1977         public static final String CMAS_CERTAINTY = "cmas_certainty";
1978 
1979         /**
1980          * The default sort order for this table
1981          */
1982         public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
1983 
1984         /**
1985          * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
1986          */
1987         public static final String[] QUERY_COLUMNS = {
1988                 _ID,
1989                 GEOGRAPHICAL_SCOPE,
1990                 PLMN,
1991                 LAC,
1992                 CID,
1993                 SERIAL_NUMBER,
1994                 SERVICE_CATEGORY,
1995                 LANGUAGE_CODE,
1996                 MESSAGE_BODY,
1997                 DELIVERY_TIME,
1998                 MESSAGE_READ,
1999                 MESSAGE_FORMAT,
2000                 MESSAGE_PRIORITY,
2001                 ETWS_WARNING_TYPE,
2002                 CMAS_MESSAGE_CLASS,
2003                 CMAS_CATEGORY,
2004                 CMAS_RESPONSE_TYPE,
2005                 CMAS_SEVERITY,
2006                 CMAS_URGENCY,
2007                 CMAS_CERTAINTY
2008         };
2009     }
2010 }
2011