【问题标题】:how to listen to contacts changes in phonebook when app is terminated(Oreo)应用程序终止时如何收听电话簿中的联系人更改(奥利奥)
【发布时间】:2018-10-29 05:57:45
【问题描述】:

我想将新联系人和电话簿中联系人的更改与我的应用程序同步....无论它像 whatsapp 一样打开还是终止。尝试使用同步适配器,但面临更新时脏标志未更改的问题。

【问题讨论】:

    标签: android android-8.1-oreo


    【解决方案1】:

    你可以使用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" />
    

    联系观察者

    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));
    

    【讨论】:

    • 这只有在应用程序处于活动状态或在后台时才有效.....应用程序终止时该怎么办??....以及如何通过此检测已编辑的联系人??跨度>
    • 谢谢..但是后台服务在奥利奥中不起作用..你在奥利奥中测试过吗??以及我们如何通过这种方法检测联系人的变化
    • 为此使用 firebase 作业调度程序
    • 我们如何使用调度程序安排基于事件的作业...您可以分享一些代码
    【解决方案2】:

    也许这会有所帮助,我没有亲自测试过。在您的活动的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 方法中,您将收到更改通知。

    【讨论】:

    • 这将只在应用程序处于活动状态时起作用,或者在应用程序终止时不起作用。
    • @Prashant : 所以你应该使用后台服务来为你完成这项工作。
    • 后台服务在oreo中被杀
    • @Prashant:请阅读此链接:developer.android.com/about/versions/oreo/background
    • 我们如何将联系人内容提供程序与作业调度程序一起使用....你见过任何例子吗??
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多