如何在应用程序终止时收听电话簿中的联系人更改(奥利奥)
how to listen to contacts changes in phonebook when app is terminated(Oreo)
我想将电话簿中的新联系人和对联系人的更改与我的应用程序同步....无论它是打开还是终止,就像 whatsapp 一样。尝试使用同步适配器,但面临更新时脏标志未更改的问题。
您可以使用 ContentObserver
参考这个link
在后台使用 运行 服务以查看联系人更改
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();
}
}
}
在清单中将其注册为服务
<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();
}
}
}
不要忘记将此添加到您的清单中
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
终于开始服务了
startService(new Intent(getBaseContext(), ContactWatchService.class));
也许这会有所帮助,我没有亲自测试过。在 activity 的 onCreate
方法中添加此代码:
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);
}
});
在 onChange
方法中,您将收到更改通知。
我想将电话簿中的新联系人和对联系人的更改与我的应用程序同步....无论它是打开还是终止,就像 whatsapp 一样。尝试使用同步适配器,但面临更新时脏标志未更改的问题。
您可以使用 ContentObserver
参考这个link
在后台使用 运行 服务以查看联系人更改
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();
}
}
}
在清单中将其注册为服务
<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();
}
}
}
不要忘记将此添加到您的清单中
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
终于开始服务了
startService(new Intent(getBaseContext(), ContactWatchService.class));
也许这会有所帮助,我没有亲自测试过。在 activity 的 onCreate
方法中添加此代码:
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);
}
});
在 onChange
方法中,您将收到更改通知。