CallLog.java revision ac835c94b81c9497404a27af4da9c957e5c82045
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
17package android.provider;
18
19import com.android.internal.telephony.CallerInfo;
20import com.android.internal.telephony.Connection;
21
22import android.content.ContentResolver;
23import android.content.ContentValues;
24import android.content.Context;
25import android.database.Cursor;
26import android.net.Uri;
27import android.text.TextUtils;
28
29/**
30 * The CallLog provider contains information about placed and received calls.
31 */
32public class CallLog {
33    public static final String AUTHORITY = "call_log";
34
35    /**
36     * The content:// style URL for this provider
37     */
38    public static final Uri CONTENT_URI =
39        Uri.parse("content://" + AUTHORITY);
40
41    /**
42     * Contains the recent calls.
43     */
44    public static class Calls implements BaseColumns {
45        /**
46         * The content:// style URL for this table
47         */
48        public static final Uri CONTENT_URI =
49                Uri.parse("content://call_log/calls");
50
51        /**
52         * The content:// style URL for filtering this table on phone numbers
53         */
54        public static final Uri CONTENT_FILTER_URI =
55                Uri.parse("content://call_log/calls/filter");
56
57        /**
58         * The default sort order for this table
59         */
60        public static final String DEFAULT_SORT_ORDER = "date DESC";
61
62        /**
63         * The MIME type of {@link #CONTENT_URI} and {@link #CONTENT_FILTER_URI}
64         * providing a directory of calls.
65         */
66        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
67
68        /**
69         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single
70         * call.
71         */
72        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
73
74        /**
75         * The type of the call (incoming, outgoing or missed).
76         * <P>Type: INTEGER (int)</P>
77         */
78        public static final String TYPE = "type";
79
80        public static final int INCOMING_TYPE = 1;
81        public static final int OUTGOING_TYPE = 2;
82        public static final int MISSED_TYPE = 3;
83
84        /**
85         * The phone number as the user entered it.
86         * <P>Type: TEXT</P>
87         */
88        public static final String NUMBER = "number";
89
90        /**
91         * The date the call occured, in milliseconds since the epoch
92         * <P>Type: INTEGER (long)</P>
93         */
94        public static final String DATE = "date";
95
96        /**
97         * The duration of the call in seconds
98         * <P>Type: INTEGER (long)</P>
99         */
100        public static final String DURATION = "duration";
101
102        /**
103         * Whether or not the call has been acknowledged
104         * <P>Type: INTEGER (boolean)</P>
105         */
106        public static final String NEW = "new";
107
108        /**
109         * The cached name associated with the phone number, if it exists.
110         * This value is not guaranteed to be current, if the contact information
111         * associated with this number has changed.
112         * <P>Type: TEXT</P>
113         */
114        public static final String CACHED_NAME = "name";
115
116        /**
117         * The cached number type (Home, Work, etc) associated with the
118         * phone number, if it exists.
119         * This value is not guaranteed to be current, if the contact information
120         * associated with this number has changed.
121         * <P>Type: INTEGER</P>
122         */
123        public static final String CACHED_NUMBER_TYPE = "numbertype";
124
125        /**
126         * The cached number label, for a custom number type, associated with the
127         * phone number, if it exists.
128         * This value is not guaranteed to be current, if the contact information
129         * associated with this number has changed.
130         * <P>Type: TEXT</P>
131         */
132        public static final String CACHED_NUMBER_LABEL = "numberlabel";
133
134        /**
135         * Adds a call to the call log.
136         *
137         * @param ci the CallerInfo object to get the target contact from.  Can be null
138         * if the contact is unknown.
139         * @param context the context used to get the ContentResolver
140         * @param number the phone number to be added to the calls db
141         * @param presentation the number presenting rules set by the network for
142         *        "allowed", "payphone", "restricted" or "unknown"
143         * @param callType enumerated values for "incoming", "outgoing", or "missed"
144         * @param start time stamp for the call in milliseconds
145         * @param duration call duration in seconds
146         *
147         * {@hide}
148         */
149        public static Uri addCall(CallerInfo ci, Context context, String number,
150                int presentation, int callType, long start, int duration) {
151            final ContentResolver resolver = context.getContentResolver();
152
153            // If this is a private number then set the number to Private, otherwise check
154            // if the number field is empty and set the number to Unavailable
155            if (presentation == Connection.PRESENTATION_RESTRICTED) {
156                number = CallerInfo.PRIVATE_NUMBER;
157                if (ci != null) ci.name = "";
158            } else if (presentation == Connection.PRESENTATION_PAYPHONE) {
159                number = CallerInfo.PAYPHONE_NUMBER;
160                if (ci != null) ci.name = "";
161            } else if (TextUtils.isEmpty(number)
162                    || presentation == Connection.PRESENTATION_UNKNOWN) {
163                number = CallerInfo.UNKNOWN_NUMBER;
164                if (ci != null) ci.name = "";
165            }
166
167            ContentValues values = new ContentValues(5);
168
169            values.put(NUMBER, number);
170            values.put(TYPE, Integer.valueOf(callType));
171            values.put(DATE, Long.valueOf(start));
172            values.put(DURATION, Long.valueOf(duration));
173            values.put(NEW, Integer.valueOf(1));
174            if (ci != null) {
175                values.put(CACHED_NAME, ci.name);
176                values.put(CACHED_NUMBER_TYPE, ci.numberType);
177                values.put(CACHED_NUMBER_LABEL, ci.numberLabel);
178            }
179
180            if ((ci != null) && (ci.person_id > 0)) {
181                ContactsContract.Contacts.markAsContacted(resolver, ci.person_id);
182            }
183
184            Uri result = resolver.insert(CONTENT_URI, values);
185
186            removeExpiredEntries(context);
187
188            return result;
189        }
190
191        /**
192         * Query the call log database for the last dialed number.
193         * @param context Used to get the content resolver.
194         * @return The last phone number dialed (outgoing) or an empty
195         * string if none exist yet.
196         */
197        public static String getLastOutgoingCall(Context context) {
198            final ContentResolver resolver = context.getContentResolver();
199            Cursor c = null;
200            try {
201                c = resolver.query(
202                    CONTENT_URI,
203                    new String[] {NUMBER},
204                    TYPE + " = " + OUTGOING_TYPE,
205                    null,
206                    DEFAULT_SORT_ORDER + " LIMIT 1");
207                if (c == null || !c.moveToFirst()) {
208                    return "";
209                }
210                return c.getString(0);
211            } finally {
212                if (c != null) c.close();
213            }
214        }
215
216        private static void removeExpiredEntries(Context context) {
217            final ContentResolver resolver = context.getContentResolver();
218            resolver.delete(CONTENT_URI, "_id IN " +
219                    "(SELECT _id FROM calls ORDER BY " + DEFAULT_SORT_ORDER
220                    + " LIMIT -1 OFFSET 500)", null);
221        }
222    }
223}
224