I have a activity which is brought in front whenever there are any outgoing call. I need the outgoing call duration in real time and show it in my activity textview.
Is this possible to get the current duration if call is in offhook?
This can be done. You just have to Spy on Android Call Log Content Provider. To use a content provider, you just need to call the getContentResolver() method. Once you have a content resolver object, you can query it using SQL or any of the built in query functions. For example, in my Android App, I use a piece of code that looks like this:
String[] strFields = {
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.TYPE,
android.provider.CallLog.Calls.CACHED_NAME,
android.provider.CallLog.Calls.CACHED_NUMBER_TYPE,
android.provider.CallLog.Calls.DURATION
};
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Cursor mCallCursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI,
strFields,
null,
null,
strOrder
);
if (callType == OUTGOING_CALL_END || callType == INCOMING_CALL_END) {
Cursor cursorCallLogs = getRecentCallLogs(context.getContentResolver());
if (cursorCallLogs != null) {
cursorCallLogs.moveToLast();
do {
try {
String callNumber = cursorCallLogs.getString(cursorCallLogs.getColumnIndex("number"));
callNumber = utilS.getPhoneNumber(callNumber);
utilS.log("Phone NUmber", callNumber);
duration = (cursorCallLogs.getInt(cursorCallLogs.getColumnIndex("duration")) * 1000);
utilS.log("durationCall", "" + duration);
} catch (Exception e) {
e.printStackTrace();
}
}
while (cursorCallLogs.moveToPrevious());
}
}
public static Cursor getRecentCallLogs(ContentResolver cr) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
return null;
} else {
return cr.query(CallLog.Calls.CONTENT_URI, null, null, null, android.provider.CallLog.Calls.DATE + " DESC limit 1");
}
}
Related
I just want to copy the incoming number and paste it to a text box. How can I do that?
Use a cursor to get any call log information you want.
String[] projection = {android.provider.CallLog.Calls._ID,
android.provider.CallLog.Calls.NUMBER,
CallLog.Calls.TYPE, CallLog.Calls.DATE};
final Cursor cursor = getActivity().getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, projection,
"type = " + CallLog.Calls.INCOMING_TYPE, null,
android.provider.CallLog.Calls.DATE + " DESC" + " LIMIT 200");
The cursor will result the number and time of call.
if (cursor.moveToFirst()) {
do {
try {
String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
String date = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE));
// Do anything with number and name
} catch (Exception e) {
}
} while (cursor.moveToNext());
}
cursor.close();
Is it possible to delete only incoming calls from the call log list?
If so how?
I am able to delete all of them easily but not sure how to delete only incoming calls?
Can somebody help me out with this?
Thanks!
In CallLog provider database, android.provider.CallLog.Calls.TYPE ("type") column will have value
android.provider.CallLog.Calls.INCOMING_TYPE (1) for an incoming call record.
Use below method with condition type = 1
public void delete(final String id, final String number) {
Uri uri = Uri.parse("content://call_log/calls");
ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(uri, null, "and type = 1 and _id" + "=?", new String[] { "" + id }, null);
if (c != null && c.moveToFirst()) {
do {
String pid = c.getString(c.getColumnIndex("_id"));
String pnumber = c.getString(c.getColumnIndex("NUMBER"));
if (id.equals(pid) && number.equals(pnumber)) {
context.getContentResolver().delete(CallLog.Calls.CONTENT_URI, CallLog.Calls._ID + " = ?", new String[] { id });
}
} while (c.moveToNext());
}
}
how can i find out the last incoming "number" that called to me?(received calls)
please don't answer following cod
it has an error (because the class extends PhoneStateListener and the method needs Activity for extending :
public class CallStat extends PhoneStateListener {
String LOG_TAG = "calllog";
private boolean isPhoneCalling = false;
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (TelephonyManager.CALL_STATE_RINGING == state) {
// phone ringing
Log.i(LOG_TAG, "RINGING, number: " + incomingNumber);
}
if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
// active
Log.i(LOG_TAG, "OFFHOOK");
isPhoneCalling = true;
}
if (TelephonyManager.CALL_STATE_IDLE == state) {
// run when class initial and phone call ended, need detect flag
// from CALL_STATE_OFFHOOK
Log.i(LOG_TAG, "IDLE number");
if (isPhoneCalling) {
Handler handler = new Handler();
//Put in delay because call log is not updated immediately when state changed
// The dialler takes a little bit of time to write to it 500ms seems to be enough
handler.postDelayed(new Runnable() {
#Override
public void run() {
// get start of cursor
Log.i("CallLogDetailsActivity", "Getting Log activity...");
String[] projection = new String[]{Calls.NUMBER};
Cursor cur = getContentResolver().query(Calls.CONTENT_URI, projection, null, null, Calls.DATE +" desc");
cur.moveToFirst();
String lastCallnumber = cur.getString(0);
}
},500);
isPhoneCalling = false;
}
}
}
}
I know for outgoing but what about incoming?
The code in the previous answer is slightly wrong I believe.
The first argument in the query method should be a URI.
See the following correction:
//fields to select.
String[] strFields = {
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.TYPE,
android.provider.CallLog.Calls.CACHED_NAME,
android.provider.CallLog.Calls.CACHED_NUMBER_TYPE
};
//only incoming.
String strSelection = android.provider.CallLog.Calls.TYPE + " = " + android.provider.CallLog.Calls.INCOMING_TYPE;
//most recent first
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
//get a cursor.
Cursor mCallCursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, //content provider URI
strFields, //project (fields to get)
strSelection, //selection
null, //selection args
strOrder //sortorder.
);
mCallCursor.moveToFirst();
String[] strFields = {
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.TYPE,
android.provider.CallLog.Calls.CACHED_NAME,
android.provider.CallLog.Calls.CACHED_NUMBER_TYPE
};
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Cursor mCallCursor = getContentResolver().query(
android.provider.CallLog.Calls.INCOMING_TYPE,
strFields,
null,
null,
strOrder
);
mCallCursor.moveToFirst();
This will return the call log of outgoing calls.
Or using your code:
Cursor cur = getContentResolver().query( android.provider.CallLog.Calls.INCOMING_TYPE, projection, null, null, Calls.DATE +" desc");
cur.moveToFirst();
String lastCallnumber = cur.getString(0);
I am developing an application, where I need to fetch the phone number from the contacts corresponding to the name provided. I have tried many codes but none of them seem to work.
Here is the code I'm currently using now
public static String getContactPhoneNumber(Context context, String contactName, int type) {
String phoneNumber = null;
String[] whereArgs = new String[] { contactName, String.valueOf(type) };
Log.d(TAG, String.valueOf(contactName));
Cursor cursor = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.Contacts.DISPLAY_NAME + " = ? and "
+ ContactsContract.CommonDataKinds.Phone.TYPE + " = ?", whereArgs, null);
int phoneNumberIndex = cursor
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER);
Log.d(TAG, String.valueOf(cursor.getCount()));
if (cursor != null) {
Log.v(TAG, "Cursor Not null");
try {
if (cursor.moveToNext()) {
Log.v(TAG, "Moved to first");
Log.v(TAG, "Cursor Moved to first and checking");
phoneNumber = cursor.getString(phoneNumberIndex);
}
} finally {
Log.v(TAG, "In finally");
cursor.close();
}
}
Log.v(TAG, "Returning phone number");
return phoneNumber;
}
On passing Contact Name (say: John Doe) and type (2 which is int value for Mobile Type), the phone number returned is null even though the contact "John Doe" exists in my contact list.
Please help!!!
Try this
instead of ContactsContract.CommonDataKinds.Phone.CONTENT_URI Pass
ContactsContract.Contacts.CONTENT_URI parameter to query method.
I am trying to get the address of the sender but I run into a little problem. If the person that sends the message is the first person in any of the conversations to send one, the query of the content://mms/inbox returns with zero rows?? but when someone sends any other mms message it will return back with the _id fine and i dont understand why the first one wont work right?
private String checkMmsMessages(Context context){
String address = "address";
Cursor curPdu = context.getContentResolver ().query(Uri.parse("content://mms/inbox"), null, null, null, null);
if(curPdu.moveToNext()){ //first MMS message curPdu.moveToNext() is false
String id = curPdu.getString (curPdu.getColumnIndex ("_id"));
Log.v("MMS", "ID1: " + id.toString());
Uri uriAddr = Uri.parse ("content://mms/" + id + "/addr");
Cursor curAddr = context.getContentResolver().query(uriAddr,null,"type=137",null,null);
if(curAddr.moveToNext()){
address = curAddr.getString (curAddr.getColumnIndex ("address"));
Log.v("MMS", "Address1: " + address.toString());
if(address.contentEquals("insert-address-token")){
Cursor curAddr2 = context.getContentResolver().query(uriAddr,null,"type=151", null,null);
if(curAddr2.moveToNext()){
address = curAddr2.getString(curAddr2.getColumnIndex("address"));
}
}
}
}
Log.v("MMS", address.toString());
return address;
}
Also something else that does not make sense is when when i have the phone plugged into the computer and step through the that section with the debugger, that problem does not happen and it gets the address every time.... it only happens when the phone is not connected, i just dont understand?
The problem was I was checking the database before the message was put into the database so I had to put a delay on the check
I think the issue is you are passing a value for selectionArgs instead of null to the query() method. I am not actually calling the mCursor's moveToNext() method in my code but instead I am implementing this logic in the getView() method of a SimpleCursorAdapter.
Uri uri = Uri.parse("content://mms-sms/conversations/" + mThreadId);
String[] projection = new String[] { "body", "person", "sub",
"subject", "retr_st", "type", "date", "ct_cls", "sub_cs",
"_id", "read", "ct_l", "st", "msg_box", "reply_path_present",
"m_cls", "read_status", "ct_t", "status", "retr_txt_cs",
"d_rpt", "error_code", "m_id", "date_sent", "m_type", "v",
"exp", "pri", "service_center", "address", "rr", "rpt_a",
"resp_txt", "locked", "resp_st", "m_size" };
String sortOrder = "normalized_date";
Cursor mCursor = getActivity().getContentResolver().query(uri,projection, null, null, sortOrder);
String messageAddress;
int type;
while (mCursor.moveToNext()) {
String messageId = mCursor.getString(mCursor.getColumnIndex("_id"));
Uri.Builder builder = Uri.parse("content://mms").buildUpon();
builder.appendPath(messageId).appendPath("addr");
Cursor c = mContext.getContentResolver().query(builder.build(), new String[] {
"*"
}, null, null, null);
while (c.moveToNext()) {
messageAddress = c.getString(c.getColumnIndex("address"));
if (!messageAddress.equals("insert-address-token")) {
type = c.getInt(c.getColumnIndex("type"));
c.moveToLast();
}
}
c.close();
}
try this...
private String getAddressNumber(String id) {
String selectionAdd = new String("msg_id=" + id);
String uriStr = MessageFormat.format("content://mms/{0}/addr", id);
Uri uriAddress = Uri.parse(uriStr);
Cursor cursor = getContentResolver().query(uriAddress, null, selectionAdd, null, null);
String phoneNum = null;
if (cursor.moveToFirst()) {
do {
String number = cursor.getString(cursor.getColumnIndex("address"));
if (number != null) {
boolean isNumberFormat = true;
try {
Long.parseLong(number.replace("-", ""));
phoneNum = number;
} catch (NumberFormatException e) { // ex) "insert-address-token"
// if (phoneNum == null) {
// phoneNum = number;
// }
isNumberFormat = false;
}
if (isNumberFormat)
break;
}
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
return phoneNum;
}