1 /* 2 * Copyright (C) 2010 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 com.android.phone.common; 18 import android.content.Context; 19 import android.os.AsyncTask; 20 import android.os.Looper; 21 import android.provider.CallLog.Calls; 22 23 /** 24 * Class to access the call log asynchronously to avoid carrying out database operations on the 25 * UI thread, using an {@link AsyncTask}. 26 * 27 * <pre class="prettyprint"> 28 * Typical usage: 29 * ============== 30 * 31 * // From an activity... 32 * String mLastNumber = ""; 33 * 34 * CallLogAsync log = new CallLogAsync(); 35 * 36 * CallLogAsync.GetLastOutgoingCallArgs lastCallArgs = new CallLogAsync.GetLastOutgoingCallArgs( 37 * this, new CallLogAsync.OnLastOutgoingCallComplete() { 38 * public void lastOutgoingCall(String number) { mLastNumber = number; } 39 * }); 40 * log.getLastOutgoingCall(lastCallArgs); 41 * </pre> 42 * 43 */ 44 45 public class CallLogAsync { 46 private static final String TAG = "CallLogAsync"; 47 48 /** 49 * Parameter object to hold the args to get the last outgoing call 50 * from the call log DB. 51 */ 52 public static class GetLastOutgoingCallArgs { 53 public GetLastOutgoingCallArgs(Context context, 54 OnLastOutgoingCallComplete callback) { 55 this.context = context; 56 this.callback = callback; 57 } 58 public final Context context; 59 public final OnLastOutgoingCallComplete callback; 60 } 61 62 /** Interface to retrieve the last dialed number asynchronously. */ 63 public interface OnLastOutgoingCallComplete { 64 /** @param number The last dialed number or an empty string if 65 * none exists yet. */ 66 void lastOutgoingCall(String number); 67 } 68 69 /** 70 * CallLog.getLastOutgoingCall(...) 71 */ 72 public AsyncTask getLastOutgoingCall(GetLastOutgoingCallArgs args) { 73 assertUiThread(); 74 return new GetLastOutgoingCallTask(args.callback).execute(args); 75 } 76 77 /** 78 * AsyncTask to get the last outgoing call from the DB. 79 */ 80 private class GetLastOutgoingCallTask extends AsyncTask<GetLastOutgoingCallArgs, Void, String> { 81 private final OnLastOutgoingCallComplete mCallback; 82 private String mNumber; 83 public GetLastOutgoingCallTask(OnLastOutgoingCallComplete callback) { 84 mCallback = callback; 85 } 86 87 // Happens on a background thread. We cannot run the callback 88 // here because only the UI thread can modify the view 89 // hierarchy (e.g enable/disable the dial button). The 90 // callback is ran rom the post execute method. 91 @Override 92 protected String doInBackground(GetLastOutgoingCallArgs... list) { 93 int count = list.length; 94 String number = ""; 95 for (GetLastOutgoingCallArgs args : list) { 96 // May block. Select only the last one. 97 number = Calls.getLastOutgoingCall(args.context); 98 } 99 return number; // passed to the onPostExecute method. 100 } 101 102 // Happens on the UI thread, it is safe to run the callback 103 // that may do some work on the views. 104 @Override 105 protected void onPostExecute(String number) { 106 assertUiThread(); 107 mCallback.lastOutgoingCall(number); 108 } 109 } 110 111 private void assertUiThread() { 112 if (!Looper.getMainLooper().equals(Looper.myLooper())) { 113 throw new RuntimeException("Not on the UI thread!"); 114 } 115 } 116 } 117