When a user changes his/her privacy settings through AppOps (e.g. denying an application access to phone contacts), AppOpsManager sends to anyone who listens what the users have changed (i.e. the package name and the operation (e.g. Read contacts)).

So I wrote a listener to do so. However, we the user make only one change, I receive too many duplicate events (e.g. 10 events that the user decided to deny Angry Bird access to his/her location) and then the app crashes.

Here is my code to register listners for each pair of package & operation:

```
public void startWatchingOperations(AppOpsManager appOps, List<AppOpsManager.PackageOps> opsforapps) {
    SharedPreferences myAppListnerPreferences = getSharedPreferences(APP_OPS_PREFERENCES, Activity.MODE_PRIVATE);
    for (AppOpsManager.PackageOps o:opsforapps) {
        List<OpEntry> opEntry = o.getOps();
        //if I already assigned a listener to this pari of package & operation, then skip 
        if (myAppListnerPreferences.getBoolean(o.getPackageName(), false)==false) {
            for (OpEntry entry:opEntry) {
                //for each pair of package & operation, assign a new listener 
                ChangePrivacySettingsListener opsListner = new ChangePrivacySettingsListener(getApplicationContext());      
                     appOps.startWatchingMode(entry.getOp(),o.getPackageName(),opsListner);
                 }
            myAppListnerPreferences.edit().putBoolean(o.getPackageName(), true).apply();
         }
    }
}

```

Here is a snippet of the listener

```
public class ChangePrivacySettingsListener implements AppOpsManager.Callback {
    public void opChanged(int op, String packageName) {
        AppOpsManager appOps=   (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
        PackageManager pkg = context.getPackageManager();
        try {
                            //this is an object to store the event: package name, 
                            // the operation that has been changed, & time stamp
            PrivacySetting privacySetting = new PrivacySetting();
            privacySetting.setPackageName(packageName);
            privacySetting.setOperation(OPERATIONS_STRINGS[op]);
            privacySetting.setDecisionTime(Calendar.getInstance(TimeZone.getDefault()).getTimeInMillis());
            privacySetting.setUserId(userId);
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
     }

```

Her is the part of AppOpsManager.java that allows me to listen to user's changes.

```
public class AppOpsManager {
    final HashMap<Callback, IAppOpsCallback> mModeWatchers
        = new HashMap<Callback, IAppOpsCallback>();

    public void startWatchingMode(int op, String packageName, final Callback callback) {
        synchronized (mModeWatchers) {
          IAppOpsCallback cb = mModeWatchers.get(callback);
          if (cb == null) {
              cb = new IAppOpsCallback.Stub() {
                  public void opChanged(int op, String packageName) {
                      callback.opChanged(op, packageName);
                  }
              };
              mModeWatchers.put(callback, cb);
          }
          try {
              mService.startWatchingMode(op, packageName, cb);
          } catch (RemoteException e) {
          }
   }
}

```

I double checked to ensure that I've never assigned more than one listener to each pair of package & operation. 

I would appreciate hints about potential causes. 

[Here is a link to AppOpsManager.java](https://android.googlesource.com/platform/frameworks/base/+/android-4.3.1_r1/core/java/android/app/AppOpsManager.java)