10ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng/* 20ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * Copyright (C) 2010 The Android Open Source Project 30ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * 40ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 50ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * you may not use this file except in compliance with the License. 60ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * You may obtain a copy of the License at 70ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * 80ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 90ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * 100ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * Unless required by applicable law or agreed to in writing, software 110ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 120ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * See the License for the specific language governing permissions and 140ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * limitations under the License. 150ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng */ 160ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 170ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Chengpackage com.android.phone.common; 180ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Chengimport android.content.Context; 190ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Chengimport android.os.AsyncTask; 200ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Chengimport android.os.Looper; 210ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Chengimport android.provider.CallLog.Calls; 220ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 230ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng/** 2445b79134b1b857b33addc4bcd2a7fd41e4295098Yorke Lee * Class to access the call log asynchronously to avoid carrying out database operations on the 2545b79134b1b857b33addc4bcd2a7fd41e4295098Yorke Lee * UI thread, using an {@link AsyncTask}. 260ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * 270ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * <pre class="prettyprint"> 280ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * Typical usage: 290ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * ============== 300ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * 310ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * // From an activity... 320ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * String mLastNumber = ""; 330ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * 340ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * CallLogAsync log = new CallLogAsync(); 350ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * 360ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * CallLogAsync.GetLastOutgoingCallArgs lastCallArgs = new CallLogAsync.GetLastOutgoingCallArgs( 370ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * this, new CallLogAsync.OnLastOutgoingCallComplete() { 380ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * public void lastOutgoingCall(String number) { mLastNumber = number; } 390ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * }); 400ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * log.getLastOutgoingCall(lastCallArgs); 410ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * </pre> 420ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * 430ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng */ 440ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 450ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Chengpublic class CallLogAsync { 460ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng private static final String TAG = "CallLogAsync"; 470ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 480ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng /** 490ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * Parameter object to hold the args to get the last outgoing call 500ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * from the call log DB. 510ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng */ 520ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng public static class GetLastOutgoingCallArgs { 530ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng public GetLastOutgoingCallArgs(Context context, 540ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng OnLastOutgoingCallComplete callback) { 550ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng this.context = context; 560ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng this.callback = callback; 570ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 580ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng public final Context context; 590ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng public final OnLastOutgoingCallComplete callback; 600ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 610ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 620ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng /** Interface to retrieve the last dialed number asynchronously. */ 630ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng public interface OnLastOutgoingCallComplete { 640ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng /** @param number The last dialed number or an empty string if 650ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * none exists yet. */ 660ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng void lastOutgoingCall(String number); 670ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 680ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 690ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng /** 700ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * CallLog.getLastOutgoingCall(...) 710ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng */ 720ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng public AsyncTask getLastOutgoingCall(GetLastOutgoingCallArgs args) { 730ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng assertUiThread(); 740ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng return new GetLastOutgoingCallTask(args.callback).execute(args); 750ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 760ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 770ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng /** 780ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng * AsyncTask to get the last outgoing call from the DB. 790ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng */ 800ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng private class GetLastOutgoingCallTask extends AsyncTask<GetLastOutgoingCallArgs, Void, String> { 810ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng private final OnLastOutgoingCallComplete mCallback; 820ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng private String mNumber; 830ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng public GetLastOutgoingCallTask(OnLastOutgoingCallComplete callback) { 840ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng mCallback = callback; 850ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 860ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 870ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng // Happens on a background thread. We cannot run the callback 880ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng // here because only the UI thread can modify the view 890ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng // hierarchy (e.g enable/disable the dial button). The 900ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng // callback is ran rom the post execute method. 910ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng @Override 920ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng protected String doInBackground(GetLastOutgoingCallArgs... list) { 930ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng int count = list.length; 940ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng String number = ""; 950ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng for (GetLastOutgoingCallArgs args : list) { 960ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng // May block. Select only the last one. 970ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng number = Calls.getLastOutgoingCall(args.context); 980ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 990ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng return number; // passed to the onPostExecute method. 1000ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 1010ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 1020ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng // Happens on the UI thread, it is safe to run the callback 1030ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng // that may do some work on the views. 1040ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng @Override 1050ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng protected void onPostExecute(String number) { 1060ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng assertUiThread(); 1070ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng mCallback.lastOutgoingCall(number); 1080ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 1090ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 1100ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng 1110ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng private void assertUiThread() { 1120ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng if (!Looper.getMainLooper().equals(Looper.myLooper())) { 1130ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng throw new RuntimeException("Not on the UI thread!"); 1140ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 1150ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng } 1160ada29ea0983ed27e33d12dfe9b1280fc7005a7eChiao Cheng} 117