I am working on an application, where i need to fetch 5 recently dialled numbers. I am able to sort the numbers in descending order, so as the recently dialled numbers comes first. I am using the following code to fetch the recent numbers.
dialledCall = (TextView)findViewById(R.id.dialledCall);
String strOrder = CallLog.Calls.DATE + " DESC";
Cursor mCallCursor = getApplicationContext().getContentResolver().query(CallLog.Calls.CONTENT_URI,
null,
CallLog.Calls.TYPE
,null,
strOrder);
mCallCursor.moveToFirst();
do {
if( i >5 )
break;
mobileNumber = mCallCursor.getString(mCallCursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
number += mobileNumber + "\n";
i++;
}
while (mCallCursor.moveToNext());
dialledCall.setText(number);
With this, i am able to sort the numbers in recent order and also i have just fetched last 5 numbers. But the query returns all the numbers, i mean Dialled, Missed and Received as well. But here i want just the dialled numbers.
I know there is something to do with CallLog.Calls.TYPE in the above query.
I have tried passing null value, but it returns all the numbers.
I also have tried CallLog.Calls.OUTGOING_TYPE in place of it, but it gives error that int value is not permitted, it should be a string value.
Any suggestions on how to replace the above code, so as to only get the dialled calls.
Note- I have already looked at https://stackoverflow.com/a/10480569/1626878, but it does not provide a solution to only fetch the dialled numbers.
You can use the CallLog class to get at this information (see http://developer.android.com/reference/android/provider/CallLog.Calls.html).
You're interested in the getLastOutgoingCall method, which returns the last phone number called.
Check the call logs. You can easily access this. Do something like,
Define,
public Cursor mCallCursor;
Then define the fields you want to obtain from the call log,
public static final String[] STR_FIELDS = {
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.DATE,
android.provider.CallLog.Calls.DURATION, android.provider.CallLog.Calls.CACHED_NUMBER_LABEL,android.provider.CallLog.Calls.NUMBER
};
Set the order,
public static final String STR_ORDER = android.provider.CallLog.Calls.DATE + " DESC";
Call the cursor.
mCallCursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI,
STR_FIELDS,
null,
null,
STR_ORDER);
I have solved the issue, so I am posting it for future visitors.
String mobileNumber="";
int i = 1;
String number = "";
TextView dialledCall;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dialledCall = (TextView)findViewById(R.id.dialledCall);
// 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 = CallLog.Calls.DATE + " DESC";
Cursor mCallCursor = getApplicationContext().getContentResolver().query(CallLog.Calls.CONTENT_URI,
null,
CallLog.Calls.TYPE + " = " + CallLog.Calls.OUTGOING_TYPE
,null,
strOrder);
mCallCursor.moveToFirst();
do {
if( i >5 )
break;
mobileNumber = mCallCursor.getString(mCallCursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
number += mobileNumber + "\n";
i++;
}
while (mCallCursor.moveToNext());
dialledCall.setText(number);
}
Here CallLog.Calls.TYPE + " = " + CallLog.Calls.OUTGOING_TYPE in the query separates out the dialled calls.
Related
I am using following to delete a number from call log. The method works fine, but for those number which contains () and - does not work fine.
public void deleteNumber(Context context, String mobile_number) {
String Calls = "content://call_log/calls";
Uri UriCalls = Uri.parse(Calls);
Cursor cur = context.getContentResolver().query(UriCalls, null, null, null, null);
Toast.makeText(context, "The number to be deleted is: " + mobile_number, Toast.LENGTH_LONG).show();
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String query = "NUMBER='" + mobile_number + "'";
int i = context.getContentResolver().delete(UriCalls, query, null);
if (i > 0) {
Toast.makeText(context, "The number " + mobile_number + " is deleted.", Toast.LENGTH_LONG).show();
break;
}
}
}
cur.close();
}
Number which are saved in this format are not deleted. Please help me to solve this.
Edit :
The following did the trick:
mobile_number = mobile_number.replaceAll("[^0-9]","");
I am using a method, which returns a mobile number. This number contains all characters including (), spaces etc. It need to be filtered.
Replace:
String query = "NUMBER='" + mobile_number + "'";
int i = context.getContentResolver().delete(UriCalls, query, null);
with:
String query = "NUMBER=?";
String[] args={ mobile_number };
int i = context.getContentResolver().delete(UriCalls, query, args);
and see if you have better luck. ( and ) are probably reserved characters and would need to be escaped. Using query parameters would solve that for you.
It's supposed to be a common problem but I don't know what is the right word to look for solution.
In my app, I user can key in a number, and I need to search if the contact exist in database. Also, given a contact ID and number, I want to find the phone label of the number..
The problem is, if I have a number in phone as "8710 2863" and my query arg is "87102863", I won't be able to get the contact and phone label... There must be a way to standardize the format.. But I can't find the way :(
Here is my code:
Cursor cursor = MyApp.getContext().getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[] {
ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.LABEL
},
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ? AND "
+ ContactsContract.CommonDataKinds.Phone.NUMBER + " = ? ",
new String[] { Long.toString(contactId), number },
ContactsContract.Data.IS_SUPER_PRIMARY + " DESC");
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
int type = cursor.getInt(0);
String label = cursor.getString(1);
String phoneLabel = (String) ContactsContract.CommonDataKinds.Phone
.getTypeLabel(MyApp.getContext().getResources(), type, label);
hashBuilder.put(Defs.ARG_PHONE_TYPE, phoneLabel);
}
} finally {
cursor.close();
}
}
Have you tried PhoneNumberUtils.formatNumber(String)?
I am working on android project and I am trying to get the numbers from the Android call log and display them in a list view.
This is working fine except for one thing, at the moment if a number has called multiple times then it is displayed multiple times within my ListView, I only want to show distinct numbers but I can't find out how this is done.
Below is the code I am using to get the numbers
String[] callLogFields = {android.provider.CallLog.Calls._ID,
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.DATE,
android.provider.CallLog.Calls.CACHED_NAME};
String viaOrder = android.provider.CallLog.Calls.DATE + " DESC";
String where = android.provider.CallLog.Calls.NUMBER + " > 0";
Cursor callLogCursor = getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI,
callLogFields, where, null, viaOrder);
ArrayList<Spanned> arrayList = new ArrayList<Spanned>();
if (callLogCursor.moveToFirst())
{
do
{
String telephoneNumber = callLogCursor.getString(callLogCursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String date = callLogCursor.getString(callLogCursor.getColumnIndex(android.provider.CallLog.Calls.DATE));
Spanned content = Html.fromHtml(telephoneNumber + "<br /><small><font color='#9f9f9f'>" + date + "</font></small>");
arrayList.add(content);
}while (callLogCursor.moveToNext());
}
Thanks for any help you can provide.
I'm working on a symptoms checker android application where user can check as many symptoms he may be having. Please do check what I have tried so far:
public String getData(String[] symptoms) {
String search = "";
Cursor c = myDataBase.query(DB_TABLE, new String[]
{KEY_CONDITIONS}, KEY_SYMPTOMS + "= ? ", symptoms, null, null, null);
c.moveToFirst();
while (c.isAfterLast() == false) {
search += c.getString(0) + ", ";
c.moveToNext();
}
return search;
}
but I will need to generate that where string dynamically, because I don't know how many symptoms will be selected. How will I accomplish this? Help from you will truly be appreciated. Thanks!
The trick is you must have one insertion character (?) for each String in your Array.
One solution is to use a loop:
String where = KEY_SYMPTOMS + " = ?";
String relation = " OR "; /* Maybe " AND "? */
StringBuilder builder = new StringBuilder(where);
for(int i = 1; i < symptoms.length; i++)
builder.append(relation).append(where);
Cursor c = myDataBase.query(DB_TABLE, new String[]
{KEY_CONDITIONS}, builder.toString(), symptoms, null, null, null);
You can also write a shorter but equivalent loop:
while (c.moveToNext())
search += c.getString(0) + ", "; // A StringBuilder should be faster
I want to get the nickname of a contact from addressbook. I start with his phone number, query it and want the nickname (aka alias) as a result.
Cursor cur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.NUMBER + " = " + incomingNumber, null, null);
if (cur.moveToFirst()) {
Log.e("saymyname", cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Nickname.NAME)));
Log.e("saymyname", cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Nickname.LABEL)));
}
Output of the logs is the incomingNumber (first Log.e() ) and null (second Log.e() ), but I want to get the contact's nickname!
Thanks
Tom
Nickname is held in a different table than the phone numbers, you have to query ContactsContract.Data.CONTENT_URI
Check my answer on this question
(I don't have necessary reputation to comment so I have to add answer)
TomTasche's answer is misleading and it got me to waste a lot of time trying to figure out why I couldn't get the proper nickname on a contact I knew had one.
I found the answer by myself but got the confirmation from this post that I was now doing it properly.
Basically when you read the ContactsContract.Data documentation you read:
Each row of the data table is typically used to store a single piece of contact information (such as a phone number) and its associated metadata (such as whether it is a work or home number).
That explains the shady part of TomTasche's code :
if (nickname.equals(incomingNumber)) {
return name;
}
Since doing a search with just the CONTACT_ID can return multiple rows (one for each information type), it's not guaranteed that the first one contains the nickname. When there is a nickname it will be in DATA1, but the phone number is also found in DATA1.
The example part in the documentation of ContactsContract.Data makes it clear that rows must be selected based on their MIME_TYPE, only when the MIME_TYPE is selected, can we start making sense of the content in the row itself.
A proper query would therefore be:
cursor = getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{Nickname.NAME},
ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + "= ?",
new String[]{contactID, Nickname.CONTENT_ITEM_TYPE},
null);
(where Nickname is ContactsContract.CommonDataKinds.Nickname)
I felt I had to say something on this topic to prevent other people wasting as much time as I did based on this sole topic (first one I found with my Google friend).
The answer from Pentium10 was very helpful! Thanks!
If anybody needs a sample, look at the following code:
public String accessContact(String incomingNumber) {
if (incomingNumber == null || "".equals(incomingNumber)) {
return "unknown";
}
try {
Cursor cur = context.getContentResolver().query(Phone.CONTENT_URI, new String[] {Phone.DISPLAY_NAME, Phone.TYPE, Phone.CONTACT_ID}, Phone.NUMBER + " = " + incomingNumber, null, null);
int nameIndex = cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIndex = cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int idIndex = cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
String name;
String type;
String id;
if (cur.moveToFirst()) {
name = cur.getString(nameIndex);
type = cur.getString(typeIndex);
id = cur.getString(idIndex);
} else {
return "unknown";
}
cur = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, new String[] {ContactsContract.Data.DATA1}, ContactsContract.Data.CONTACT_ID + " = " + id, null, null);
int nicknameIndex = cur.getColumnIndex(ContactsContract.Data.DATA1);
String nickname;
if (cur.moveToFirst()) {
nickname = cur.getString(nicknameIndex);
if (nickname.equals(incomingNumber)) {
return name;
}
return nickname;
} else {
return name;
}
} catch (Exception e) {
e.printStackTrace();
return "unknown";
}