I am new to android development.
I want to monitor the changes occurred in the call log.My code is fetching all the call history until the last recent call log.when I run my app it again fetches all the logs including the newest one but I want only the latest changes. Please guide me how can I achieve this with contentOberser ? Please help. this is my code
private void conatctDetails()
{
StringBuffer sb = new StringBuffer();
Cursor c1 = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.Contacts.DISPLAY_NAME);
sb.append("Contact details:");
try
{
while(c1.moveToNext())
{
String id = c1.getString(c1.getColumnIndex(ContactsContract.Contacts._ID));
String name =c1.getString(c1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String timesContacted =c1.getString(c1.getColumnIndex(ContactsContract.Contacts.TIMES_CONTACTED));
String lastTimeContacted =c1.getString(c1.getColumnIndex(ContactsContract.Contacts.LAST_TIME_CONTACTED));
String number="";
// String number =c1.getString(c1.getColumnIndex(CommonDataKinds.Phone.NUMBER));
if(id==null||name==null)
continue;
Cursor cur = getContentResolver().query(CommonDataKinds.Phone.CONTENT_URI, null, CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
if(cur==null)
continue;
number = "";
while(cur.moveToNext())
{
number = cur.getString(cur.getColumnIndex(CommonDataKinds.Phone.NUMBER));
sb.append("\n Contact Number:--"+number);
}
sb.append("\n Contact Name:--"+name+"\n Contact ID:--"+id+"\n Last Time Contacted:--"+lastTimeContacted+"\n Total Time Contacted:--"+timesContacted);
sb.append("\n----------------------------");
}
//c1.close();
contact.setText(sb);
}
catch(Exception e)
{
}
finally
{
c1.close();
}
}
If there is an Intent that is fired on an incoming call you could get your app to respond by using a BroadcastReceiver and create an IntentFilter in your manifest.
Or just query the provider when your app launches...
ACTION_PHONE_STATE_CHANGED is a TelephonyManager intent you can listen for and check if it is TelephonyManager.CALL_STATE_RINGING.
Related
I found two answers on Stackoverflow on how to delete SMS messages programmatically. I'm running this on an app which is set to be the default messaging app.
I have tried these two codes
This one which is supposed to delete everything. It deleted most, but about 4-5 did not get deleted.
this.getApplicationContext().getContentResolver().delete(Uri.parse("content://sms/"), null, null);
and this one, which removed less then the code above
Uri inboxUri = Uri.parse("content://sms/inbox");
int count = 0;
Cursor c = context.getContentResolver().query(inboxUri , null, null, null, null);
while (c.moveToNext()) {
try {
// Delete the SMS
String pid = c.getString(0); // Get id;
String uri = "content://sms/" + pid;
count = context.getContentResolver().delete(Uri.parse(uri),
null, null);
} catch (Exception e) {
}
}
Any idea why a few messages are not being deleted? Any other way to delete all the SMS/MMS messages on the phone?
So I've written a query to extract the WhatsApp contacts of a phone. My initial query goes like this:
Cursor c = con.getContentResolver().query(
ContactsContract.RawContacts.CONTENT_URI,
new String[]{ContactsContract.RawContacts.CONTACT_ID, ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY},
ContactsContract.RawContacts.ACCOUNT_TYPE + "= ?",
new String[]{"com.whatsapp"},
null
);
ArrayList<String> myWhatsappContacts = new ArrayList<String>();
int contactNameColumn = c.getColumnIndex(ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY);
while (c.moveToNext()) {
// You can also read RawContacts.CONTACT_ID to read the
// ContactsContract.Contacts table or any of the other related ones.
myWhatsappContacts.add(c.getString(contactNameColumn));
}
The purpose of this is to find out how many WhatsApp contacts the phone has at any one time. When I do:
Log.i("WhatsApp contacts found:", Integer.toString(myWhatsappContacts.size());
It should print out how many WhatsApp contacts there were into LogCat. And this works - up to a point.
Let's say for example that the number of WhatsApp contacts I have now is 101. The next phase of this little project is to delete away ALL contacts if there are more than 100 of them. In which case, we go:
if (myWhatsappContacts.size() > 100) {
//Delete all contacts code here
}
I've tested the delete contacts code, it works. I check the contacts directory of the phone via the contacts app, and it says 0. But now when I do the query again (refer to code above), it still shows 101! What's going on?
If it helps, my DeleteContacts method is as follows:
private void deleteContact(Context ctx, String phone, String name) {
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null);
try {
if (cur.moveToFirst()) {
do {
if (cur.getString(cur.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) {
String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
ctx.getContentResolver().delete(uri, null, null);
return;
}
} while (cur.moveToNext());
}
} catch (Exception e) {
System.out.println(e.getStackTrace());
} finally {
cur.close();
}
return;
}
What am I doing wrong? Is my DeleteContacts code faulty? Or is the query itself faulty?
I implemented a code to retrieve all contacts but it is not showing all contacts where few of them are missed.
Here is my code:
String[] projection = new String[]{
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER,
};
Cursor cursor = null;
try {
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, null, null, null);
} catch (SecurityException e) {
}
if (cursor != null) {
try {
HashSet<String> normalizedNumbersAlreadyFound = new HashSet<>();
int indexOfNormalizedNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER);
int indexOfDisplayName = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int indexOfDisplayNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
while (cursor.moveToNext()) {
String normalizedNumber = cursor.getString(indexOfNormalizedNumber);
if (normalizedNumbersAlreadyFound.add(normalizedNumber)) {
String displayName = cursor.getString(indexOfDisplayName);
String displayNumber = cursor.getString(indexOfDisplayNumber);
listOfContacts.add(new PhoneContactsModel(displayName, displayNumber, false));
} else {
}
}
Log.d("tag", "size of listOfContacts =1====" + listOfContacts.size());
} finally {
cursor.close();
}
}
don't know what is happening. Please help me.
There are many issues in the code:
You're querying over the CommonDataKinds.Phone.CONTENT_URI table, so naturally, you won't get contacts that have no phone numbers (e.g. contacts with name and email)
You're skipping contacts that contains phones you've already encountered in normalizedNumbersAlreadyFound, so if you have two contacts with a shared phone (like a home phone number) you might skip one of them.
CommonDataKinds.Phone.NORMALIZED_NUMBER may be null, in which case you'll skip many contacts that do not have their NORMALIZED_NUMBER field set
If you need to also include contacts that have no phones, I would recommend a completely different code. If you only need to get contacts with phones, I would recommend not relying on NORMALIZED_NUMBER, and instead add CommonDataKinds.Phone.CONTACT_ID to your projection, and have that as your unique key per contact.
I am very new android developer and i'm trying to fill a autocompletetextview with contact display names, and when a suggestion is clicked i want it to autofill the email field from that contact. I managed to get it working, but my problem is speed. Because I need to get the email address of all contacts, I need to do a query for every single contact, which takes a very long time when I have about 3000 contacts on the device i'm testing on. The thing is, most of the contacts don't even have an email address, but I still need to do a query to discover that. I am getting the contacts via an async task. Here is the
doInBackground of the AsyncTask:
protected Object[] doInBackground(ContentResolver...cr) {
try{
List<String> names = new ArrayList<String>();
Map<Integer, String> emails = new HashMap<Integer, String>();
Map <Integer, List<String>> contacts = new HashMap<Integer, List<String>>();
/*********** Reading Contacts Name **********/
//Query to get contact name
Cursor cur = cr[0]
.query(ContactsContract.Contacts.CONTENT_URI,
null,
null,
null,
null);
// If data data found in contacts
if (cur.getCount() > 0) {
Log.i("AutocompleteContacts", "Reading contacts........");
String name = "";
String id = "";
while (cur.moveToNext())
{
name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String email = "";
if(name != null)
{
names.add(name.toString());
}
Cursor cur1 = cr[0].query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null);
if(cur1.getCount()>0)
{
while(cur1.moveToNext())
{
email = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
if(email != null)
{
emails.put(Integer.parseInt(id), email);
}
}
}
cur1.close();
List<String> line = new ArrayList<String>();
line.add(name);
line.add(email);
contacts.put(Integer.parseInt(id), line);
} // End while loop
} // End Cursor value check
else
{
Log.i("contacts", "No contacts found");
}
cur.close();
results[0] = names;
results[1] = contacts;
results[2] = emails;
} catch (NullPointerException e) {
Log.i("AutocompleteContacts","Exception : "+ e);
}
return results;
}
Basically my question is: Is there a way to check if the contact has an email without another query like HAS_EMAIL_ADDRESS column or something.
If you want to view the full source of my app: https://github.com/michael-elgavi/perlib
After thinking for a while a realized I only need the email of the contact that you click on, so I just removed the email code from the asynctask and made another asynctask that loads an email of a specific contact. Then I get the email of the contact that was clicked and fill the email field. Code can be found in the repository I linked to in the question.
Is it possible to have a broadcast receiver or service to be notified when a phone contact is added, deleted or modified?
I am making an application that needs fast access to phone contact, for what i was thinking of one copy sqlite phone contacts as accessed through contactsContracts.
If it's not possible, Does anyone know how to improve the response speed of the following code to see if a number is in the phone's contact list?
public boolean isNumberInContacts(String Num){
try {
Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext()) {
String colID = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (Integer.parseInt(hasPhone)==1) {
Cursor phone = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ colID,null, null);
for (int i=0;phone.moveToNext();i++){
if (Num.equals(mNumber.getNumber((phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)))))){
return true;
}
}
}
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "Error when validate number in contacts: "+ e.toString());
}
return false;
}
Thanks
no broadcast when a contact is added. register a content observer in the contacts database to check for changes to it.