Android ContentObserver 學習
阿新 • • 發佈:2019-01-31
從觀察者列表中獲取內容觀察者(Transport), 然後呼叫onChange./** * Notify observers of a particular user's view of the provider. * @param userHandle the user whose view of the provider is to be notified. May be * the calling user without requiring any permission, otherwise the caller needs to * hold the INTERACT_ACROSS_USERS_FULL permission. Pseudousers USER_ALL and * USER_CURRENT are properly interpreted; no other pseudousers are allowed. */ @Override public void notifyChange(Uri uri, IContentObserver observer, boolean observerWantsSelfNotifications, boolean syncToNetwork, int userHandle) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Notifying update of " + uri + " for user " + userHandle + " from observer " + observer + ", syncToNetwork " + syncToNetwork); } // Notify for any user other than the caller's own requires permission. final int callingUserHandle = UserHandle.getCallingUserId(); if (userHandle != callingUserHandle) { mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS, "no permission to notify other users"); } // We passed the permission check; resolve pseudouser targets as appropriate if (userHandle < 0) { if (userHandle == UserHandle.USER_CURRENT) { userHandle = ActivityManager.getCurrentUser(); } else if (userHandle != UserHandle.USER_ALL) { throw new InvalidParameterException("Bad user handle for notifyChange: " + userHandle); } } final int uid = Binder.getCallingUid(); // This makes it so that future permission checks will be in the context of this // process rather than the caller's process. We will restore this before returning. long identityToken = clearCallingIdentity(); try { ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); synchronized (mRootNode) { mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications, userHandle, calls); } final int numCalls = calls.size(); for (int i=0; i<numCalls; i++) { ObserverCall oc = calls.get(i); try { oc.mObserver.onChange(oc.mSelfChange, uri, userHandle); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Notified " + oc.mObserver + " of " + "update at " + uri); } } catch (RemoteException ex) { synchronized (mRootNode) { Log.w(TAG, "Found dead observer, removing"); IBinder binder = oc.mObserver.asBinder(); final ArrayList<ObserverNode.ObserverEntry> list = oc.mNode.mObservers; int numList = list.size(); for (int j=0; j<numList; j++) { ObserverNode.ObserverEntry oe = list.get(j); if (oe.observer.asBinder() == binder) { list.remove(j); j--; numList--; } } } } } if (syncToNetwork) { SyncManager syncManager = getSyncManager(); if (syncManager != null) { syncManager.scheduleLocalSync(null /* all accounts */, callingUserHandle, uid, uri.getAuthority()); } } } finally { restoreCallingIdentity(identityToken); } }