当用户通过AppOps更改他/她的隐私设置(例如,拒绝应用程序访问电话联系人)时,AppOpsManager会向任何监听用户更改内容的人发送消息(例如,包名和操作(例如,读取联系人))。
所以我写了一个监听器来做这件事。然而,我们用户只做了一次更改,我收到了太多重复的事件(例如,用户决定拒绝愤怒的小鸟访问他/她的位置的10个事件),然后应用程序崩溃。
下面是我为每对包和操作注册监听器的代码:
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();
}
}
}以下是监听程序的一个片段
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是AppOpsManager.java的一部分,它允许我监听用户的更改。
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) {
}
}
}我仔细检查了一下,以确保我从未为每对包和操作分配超过一个侦听器。
对于潜在原因的提示,我将不胜感激。
发布于 2014-04-30 12:40:57
尝试将ChangePrivacySettingsListener opsListner的减速移到for块的外侧:
public void startWatchingOperations(AppOpsManager appOps, List<AppOpsManager.PackageOps> opsforapps) {
ChangePrivacySettingsListener opsListner;
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
opsListner = new ChangePrivacySettingsListener(getApplicationContext());
appOps.startWatchingMode(entry.getOp(),o.getPackageName(),opsListner);
}
myAppListnerPreferences.edit().putBoolean(o.getPackageName(), true).apply();
}
}}
请让我知道发生了什么事?
发布于 2018-01-06 22:07:12
如果这对某些人有帮助,至少是Android Oreo,调用AppOpsManager.startWatchingMode(op, packageName, callback)将导致callback在设置更改时被调用(1)对于任何软件包的op,和 (2)对于任何AppOps设置随packageName的更改。这可以从AppOpsService.java源代码中看出,特别是注册回调的AppOpsService.startWatchingMode(),以及当AppOps设置更改时调用回调的AppOpsService.setMode()。
例如,如果您使用startWatchingMode(appOps1, package1, callback)和startWatchingMode(appOps2, package1, callback)注册回调,当package1的appOps3设置发生变化时,该回调将被调用两次,因为您已经注册了两次package1。如果package1的appOps1发生变化,回调会被调用三次,因为您已经注册了一次appOps1,两次package1。
解决方案是注册您感兴趣的AppOps集(无重复),将packageName参数设置为null,或者注册您感兴趣的包集,将op参数设置为AppOpsManager.OP_NONE。
此外,您还需要确保使用stopWatchingMode取消注册所有侦听器(例如,在您活动的onDestroy中)。否则,回调条目将在Activity生命周期中累积(直到应用程序终止),您将开始获得重复项。这也意味着您应该保留对创建的所有侦听器的引用。
https://stackoverflow.com/questions/23379077
复制相似问题