Get phone call information on android - android

I've been trying to figure out how to develop a requirement of one of my projects. The requirement is to get information about phone calls:
Timestamp and phone number of ingoing/outgoing calls
Timestamp and reason of finished call (call ended by user, network unreachable...)
What I found until now is not so much. This next link
http://developer.android.com/reference/android/telephony/PhoneStateListener.html
Talks about creating a listener to get incoming calls phone number.
Anyone can help me with the rest of functionality? where to get the outgoing information of phone calls? Is there any way to know when a phone call is finished, and the reason?
Thank you in advance,

private void getCallLogDetail( Context context ) {
String[] projection = new String[] {
BaseColumns._ID,
CallLog.Calls.NUMBER,
CallLog.Calls.TYPE,
CallLog.Calls.DURATION
};
ContentResolver resolver = context.getContentResolver();
Cursor cur = resolver.query(
CallLog.Calls.CONTENT_URI,
projection,
null,
null,
CallLog.Calls.DEFAULT_SORT_ORDER );
if( !cur.isAfterLast()) {
int numberColumn = cur.getColumnIndex( CallLog.Calls.NUMBER );
int typeColumn = cur.getColumnIndex( CallLog.Calls.TYPE );
int durationcolumn = cur.getColumnIndex(CallLog.Calls.DURATION);
String number = cur.getString( numberColumn );
String type = cur.getString( typeColumn );
String duration = cur.getString(durationcolumn);
cur.moveToNext();
}
}

Related

How to get the default CALENDAR_ID in Android?

I am trying to add Events in my app using a calender.According to CalenderContract,I need to provide a constant ID each time I add an event to the calender.I don't know how to do that.
I tried using calender_ID =1 which worked on some devices and calender_ID = 3 which also worked on some devices.
I think there would be some default ID which can be used to make this work properly.
Can anyone please tell me how this can be done?
Thanks in Advance.
you can get the calender id by this following code :
String projection[] = {"_id", "calendar_displayName"};
Uri calendars;
calendars = Uri.parse("content://com.android.calendar/calendars");
ContentResolver contentResolver = c.getContentResolver();
Cursor managedCursor = contentResolver.query(calendars, projection, null, null, null);
if (managedCursor.moveToFirst()){
m_calendars = new MyCalendar[managedCursor.getCount()];
String calName;
String calID;
int cont= 0;
int nameCol = managedCursor.getColumnIndex(projection[1]);
int idCol = managedCursor.getColumnIndex(projection[0]);
do {
calName = managedCursor.getString(nameCol);
calID = managedCursor.getString(idCol);
m_calendars[cont] = new MyCalendar(calName, calID);
cont++;
} while(managedCursor.moveToNext());
managedCursor.close();
}
So you can get the calender Id at runtime and use it . you don't need hardcoded 1 or 3 column Id.

How to retrieve phone numbers/photo id/firstname/lastname within a single request?

I'm currently using the answer to this question: How to get all contacts first name, last name, email, phone number, etc without duplicates to retrieve the user contact list with, for each contact, all phone numbers, the firstname, lastname and the photo id.
The issue I've with that answer is it's creating one request per data wanted. It's creating performances issues on my app. I would like to retrieve all these information from a single request, but I've got a lot of difficulty to understand how Android's query are managed and where are stored data I'm looking for.
Example of what I've tried (I've done a lot of test without success, following one is the last one I've tried):
new CursorLoader(
this,
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.HAS_PHONE_NUMBER + "!=0 AND (" + ContactsContract.Data.MIMETYPE + "=?)",
new String[]{ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE},
ContactsContract.Data.CONTACT_ID)
;
And information I would like to retrieve:
int firstNameCol = cursor.getColumnIndex(CommonDataKinds.StructuredName.GIVEN_NAME);
int lastNameCol = cursor.getColumnIndex(CommonDataKinds.StructuredName.FAMILY_NAME);
int photoIdCol = cursor.getColumnIndex(CommonDataKinds.StructuredName.PHOTO_ID);
int phoneCol = cursor.getColumnIndex(Phone.NUMBER);
There is two issues with that request:
I only get one phone number per contact, however some of my contacts have several numbers and I would like to retrieve them
I'm not retrieving the firstname and the lastname (I get a weird number instead)
Please note that I don't want to retrieve the DISPLAY_NAME, I want both given_name and family_name. Please also note I would like to have one result per contact and not one result per phone number (i.e one result contain one to many phone numbers)
Any idea to do that in a single request?
EDIT: trying with another piece of code from #pskink but I get a "column '_id' does not exists" error
String[] projection = {
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
ContactsContract.CommonDataKinds.StructuredName.PHOTO_ID
};
String selection = ContactsContract.Data.MIMETYPE + " in (?, ?, ?, ?)";
String[] selectionArgs = {
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
ContactsContract.CommonDataKinds.StructuredName.PHOTO_ID
};
//String sortOrder = ContactsContract.Contacts.SORT_KEY_ALTERNATIVE;
//Uri uri = ContactsContract.CommonDataKinds.Contactables.CONTENT_URI;
Uri uri = ContactsContract.Data.CONTENT_URI;
// ok, let's work...
return new CursorLoader(
this, uri, projection, selection, selectionArgs, null
);
Thanks to #pskink, I've now a fast single request to retrieve what I want. Unfortunately, I cannot use the CursorAdapter and I've to request the whole DB and store result in an object model, but the result is very fast so it's OK.
Here's the complete code:
public ArrayList<ContactModel> retrieveContactList(){
ArrayList<ContactModel> list = new ArrayList<>();
LongSparseArray<ContactModel> array = new LongSparseArray<>();
Set<String> set = new HashSet<String>();
set.add(ContactsContract.Data.MIMETYPE);
set.add(ContactsContract.Data.CONTACT_ID);
set.add(ContactsContract.Data.PHOTO_ID);
set.add(ContactsContract.CommonDataKinds.Phone.NUMBER);
set.add(ContactsContract.CommonDataKinds.Phone.TYPE);
set.add(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
set.add(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
set.add(ContactsContract.Contacts.PHOTO_ID);
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = set.toArray(new String[0]);
String selection = ContactsContract.Data.MIMETYPE + " in (?, ?)";
String[] selectionArgs = {
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
};
String sortOrder = ContactsContract.Contacts.SORT_KEY_ALTERNATIVE;
Cursor cursor = this.context.getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder
);
final int mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE);
final int idIdx = cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID);
final int phoneIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
final int phoneTypeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
final int givenNameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
final int familyNameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
final int photoIdIdx = cursor.getColumnIndex(ContactsContract.Data.PHOTO_ID);
while (cursor.moveToNext()) {
long id = cursor.getLong(idIdx);
ContactModel addressBookContact = array.get(id);
if (addressBookContact == null) {
addressBookContact = new ContactModel(id);
array.put(id, addressBookContact);
list.add(addressBookContact);
}
Long photoId = cursor.getLong(photoIdIdx);
if (photoId != null){
addressBookContact.addPhotoId(photoId);
}
switch (cursor.getString(mimeTypeIdx)) {
case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
// row's data: see ContactsContract.CommonDataKinds.Phone
addressBookContact.addPhone(cursor.getInt(phoneTypeIdx), cursor.getString(phoneIdx));
break;
case ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE:
// row's data: see ContactsContract.CommonDataKinds.StructuredName
addressBookContact.addName(cursor.getString(givenNameIdx), cursor.getString(familyNameIdx));
break;
}
}
cursor.close();
return list;
}

Frequent queries on android contacts returns null

I'm using the following code segment to get phone numbers of a contact by contact ID
private static ArrayList<PhoneName> getPhonesFromID(Context context,
String contactID, String column) {
// Run query
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.STARRED,
ContactsContract.CommonDataKinds.Phone.TYPE };
String selection = column + " = '" + contactID + "'";
String[] selectionArgs = null;
String sortOrder = ContactsContract.CommonDataKinds.Phone.NUMBER
+ " COLLATE LOCALIZED ASC";
Cursor cursor = context.getContentResolver().query(uri, projection,
selection, selectionArgs, sortOrder);
if (cursor == null)
return null;
int numberIndex = cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int nameIndex = cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int typeIndex = cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int favIndex = cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.STARRED);
ArrayList<PhoneName> phones = new ArrayList<PhoneName>();
while (cursor.moveToNext()) {
PhoneName pn = new PhoneName();
pn.name = cursor.getString(nameIndex);
pn.number = cursor.getString(numberIndex);
pn.starred = cursor.getString(favIndex);
pn.state = DataHelper.getInstance(context)
.getSubscriptionStateByNumber(pn.number);
Log.d("Number", pn.number);
int type = cursor.getInt(typeIndex);
if (type == ContactsContract.CommonDataKinds.Phone.TYPE_HOME) {
pn.type = "Home";
} else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) {
pn.type = "Mobile";
} else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_WORK) {
pn.type = "work";
} else {
pn.type = "other";
}
phones.add(pn);
}
cursor.close();
return phones;
}
Here's PhoneName is my self-defined class to store contact information of that specific contact. This function is called like:
getPhonesFromID(context, _id,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
I'm getting the contact information correctly but here's the problem, sometimes this function returns null when I make frequent queries. When this problem occurs, default people application of my android don't show any contact too. All contacts are like vanished. Then if I close my application and restart then it shows all contacts like before. Then again when I go to the contact details of a contact from my application it works fine several times and then all contacts are gone again.
This is a weird problem and I don't know actually what is happening here. I double checked my queries and couldn't figure out what's wrong in here.
Finally, this problem got solved.
Like I said, my application is like Phonebook and I had to show a favourite icon for each contact in the list which is my favourite contact. In my case, I had a function like isFavourite() to determine if a contact is in my favourite list or not and this is called in every single time when a contact row is loading.
Each time I open a cursor to get the query result and it was found that the cursor was not closed anywhere. So basically, closing the cursor properly solved the problem! Cheers!

How to get used data log android

Is there a way how to get data log like you can get sms or call log?
ContentResolver contentResolver = context.getContentResolver();
Cursor c = contentResolver.query(CallLog.Calls.CONTENT_URI, null,
null, null, CallLog.Calls.DATE + " DESC");
int number = c.getColumnIndex(CallLog.Calls.NUMBER);
int type = c.getColumnIndex(CallLog.Calls.TYPE);
int date = c.getColumnIndex(CallLog.Calls.DATE);
int duration = c.getColumnIndex(CallLog.Calls.DURATION);
I need to know how many data I used by mobile connection (no wifi) last month to count with that in future.

How to fast the contacts loading in listview on android

in my app i am listing contacts in a listview. no of contacts is 1000+. i get the contacts
by using ContentResolver query that is cr.query(...),store the values in an arraylist
and after that load the array list in setListAdapter(...). to display the all contacts my
apps takes nearly 1 minute so that i use Async task but there is no big differences by using the async task.
i need to display all contacts within 2 to 4 seconds. i check in the default contacts
application on android simulator which is load within in 2 to 4 seconds. i have spend
long time in google. but i could not get any helpful solution. please help me how to fast the loading contacts on listview. please help me.
my coding sample:
private ArrayList<ContactListEntry> loadContactListInternal(String searchString) {
ArrayList<ContactListEntry> contactList = new ArrayList<ContactListEntry>();
ContentResolver cr = getContentResolver();
Cursor cur = null;
String[] projection = new String[] {BaseColumns._ID,ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts.PHOTO_ID};
....
cur=cr.query(ContactsContract.Contacts.CONTENT_URI, projection, selection, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
while (cur.moveToNext()) {
int id = Integer.parseInt(cur.getString(0));
....
if (input !=null)
photo = BitmapFactory.decodeStream(input);
....
ArrayList<ContactListEntry.PhoneEntry> phoneEntries = new ArrayList<ContactListEntry.PhoneEntry>();
String[] projection1 = new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone.TYPE};
Cursor pcur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,projection1, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { String.valueOf(id) }, null);
while (pcur.moveToNext()) {
...
}
pcur.close();
ContactListEntry entry = new ContactListEntry(id, name, photo, phoneEntries);
contactList.add(entry);
}
cur.close();
return contactList;
}
.....
in another class
private void selectionUpdated() {
....
setListAdapter(new SelectedArrayAdapter(this, app.selectedContacts));
...
}
Use the Concept of projections and selection arguments to retrive the contacts in my case for 500 contacts intially it was taking 12 sec.
Now it is taking 350ms(lessthan second)
void getAllContacts() {
long startnow;
long endnow;
startnow = android.os.SystemClock.uptimeMillis();
ArrayList arrContacts = new ArrayList();
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Cursor cursor = ctx.getContentResolver().query(uri, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.Contacts._ID}, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
cursor.moveToFirst();
while (cursor.isAfterLast() == false) {
String contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
int phoneContactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
int contactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Log.d("con ", "name " + contactName + " " + " PhoeContactID " + phoneContactID + " ContactID " + contactID)
cursor.moveToNext();
}
cursor.close();
cursor = null;
endnow = android.os.SystemClock.uptimeMillis();
Log.d("END", "TimeForContacts " + (endnow - startnow) + " ms");
}
More information on this link http://www.blazin.in/2016/02/loading-contacts-fast-from-android.html ....
So your problem is that you do a lot of subqueries for each contact. I has the same issue once upon a time. My case was that I showed many contacts and allowed the user to click on any of them. After that I started processing the contact in another activity.
Back then I finally decided that I should display only the name and lazily fetch all the other data later on, just before I launch the next activity. This was amazing: decreased the speed of my program almost by a factor of 200, and the operations became completely invisible to the user.
The default android list does the same if I am not wrong - it displays only the name, and later on loads all the other contact-related data.
i use cursor adapter and i cut the databse,arrayadapter and optimize the code.
Consider having just one query and getting rid of the sub query idea (as already suggested). You can achieve speed by just querying using the Content Uri:
"ContactsContract.CommonDataKinds.Phone.CONTENT_URI"
This URI also has the "ContactsContract.Contacts.DISPLAY_NAME" field.
You might also want to consider doing this query and working with your adapter in a seperate thread to make it completely transparent.
This worked for me.
OPTIMIZED SOLUTION HERE.....
private static final String[] PROJECTION = new String[] {
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
.
.
.
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null);
if (cursor != null) {
try {
final int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String name, number;
while (cursor.moveToNext()) {
name = cursor.getString(nameIndex);
number = cursor.getString(numberIndex);
}
} finally {
cursor.close();
}
}
CHEERS...:)

Categories

Resources