Prashant
Prashant

Reputation: 3

how to listen to contacts changes in phonebook when app is terminated(Oreo)

I want to sync new contact and changes to contacts in Phonebook with my app....whether its open or terminated like whatsapp do. Tried with sync adapter but facing issues as dirty flag not changing on update.

Upvotes: 0

Views: 1775

Answers (2)

sourabh kaushik
sourabh kaushik

Reputation: 523

You can use ContentObserver

Refer to this link

Use service to run in background for watching contact change

public class ContactWatchService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }
    @Override
    public void handleMessage(Message msg) {
        try {
            //Register contact observer
            startContactObserver();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
private void startContactObserver(){
    try{
        //Registering contact observer
        getApplication().getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true,new ContObserver(new Handler(),getApplicationContext()));
    }catch (Exception e){
        e.printStackTrace();
    }
}

@Override
public void onCreate() {
    // Start up the thread running the service.  Note that we create a
    // separate thread because the service normally runs in the process's
    // main thread, which we don't want to block.  We also make it
    // background priority so CPU-intensive work will not disrupt our UI.
    HandlerThread thread = new HandlerThread("ServiceStartArguments");
    thread.start();

    // Get the HandlerThread's Looper and use it for our Handler
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    // For each start request, send a message to start a job and deliver the
    // start ID so we know which request we're stopping when we finish the job
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    mServiceHandler.sendMessage(msg);

    // If we get killed, after returning from here, restart
    return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    // We don't provide binding, so return null
    return null;
}
@Override
public void onDestroy() {
    super.onDestroy();

    try{
        //Code below is commented.
        //Turn it on if you want to run your service even after your app is closed
        /*Intent intent=new Intent(getApplicationContext(), ContactWatchService.class);
        startService(intent);*/
    }catch (Exception e){
        e.printStackTrace();
    }
}
 }

Register this as service in manifest

 <service
        android:name=".service.syncAdapter.ContactWatchService"
        android:enabled="true"
        android:exported="false" />

ContactObserver

public class ContObserver extends ContentObserver {

Context context;


@Override
public void onChange(boolean selfChange, Uri uri) {
    super.onChange(selfChange, uri);

   contactAdded(selfChange);
}

public void contactAdded(boolean selfChange) {
    if (!selfChange) {
        try {
            if (ActivityCompat.checkSelfPermission(context,
                    Manifest.permission.READ_CONTACTS)
                    == PackageManager.PERMISSION_GRANTED) {
                ContentResolver cr = context.getContentResolver();
                Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
                if (cursor != null && cursor.getCount() > 0) {
                    //moving cursor to last position
                    //to get last element added
                    cursor.moveToLast();
                    String contactName = null, photo = null, contactNumber = null;
                    String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));

                    if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                        Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
                        if (pCur != null) {
                            pCur.moveToFirst();
                            contactNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                            contactName = pCur.getString(pCur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                           //here you will get your contact information


                        }
                        pCur.close();
                    }
                    cursor.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Do not forget to add this in your manifest

 <uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />

finally start service

startService(new Intent(getBaseContext(), ContactWatchService.class));

Upvotes: 2

Shayan Tabatabaee
Shayan Tabatabaee

Reputation: 467

Maybe this will be helpful, I do not test this personally. in onCreate method of your activity add this code :

getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, new ContentObserver() {
            @Override
            public boolean deliverSelfNotifications() {
                return super.deliverSelfNotifications();
            }

            @Override
            public void onChange(boolean selfChange) {
                super.onChange(selfChange);
            }

            @Override
            public void onChange(boolean selfChange, Uri uri) {
                super.onChange(selfChange, uri);
            }
        });

In onChange method you will notified by the changes.

Upvotes: 0

Related Questions