第三方应用监听Settings.Global中的属性变化。
监听Settings.Global中的属性
Uri uri = Settings.Global.getUriFor("sound_style");
ContentObserver observer = new ContentObserver(App.handler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
}
};
App.context.getContentResolver().registerContentObserver(uri, true, observer);
App.context.getContentResolver().unregisterContentObserver(observer);
1、uri,要监听哪一个字段。未注册的字段不监听。
uri还有一种写法,Uri uri = Settings.Global.CONTENT_URI.buildUpon().appendPath("sound_style").build();二者打印均为:content://settings/global/sound_style,但实际使用上述代码中实例。
2、通知哪个属性变化,但不告诉新值;原为x,再次设置为x,不会触发onChange。
需求来源
开机后需要设置SoundStyle,后来新增需求,要把Sound的设置恢复为defaul,这其中包含SoundStyle,但SoundStyle的设置还得有效。但reset Sound有几个坑,1、他的执行时间比较长,且波动较大,从3秒到20秒;2、他不在调用它的线程里顺序执行,而只是设置一个标志位,Framework层监听并完成业务;3、没有执行完成的回调。
想到延时的策略,先reset Sound,5秒后在设置SoundStyle。此方法在多批次测试通过。但忽然某一天,有一台机器报设置无效,分析,是设置了但又被reset了,改为延时10秒。插一句,其实延时10秒,就给了用户手动修改的机会了。应用无法区分是reset业务修改的,还是用户手动修改的,手动修改按说不能被应用再修改的,但为了解决临头的bug,也就这么改了,回归通过。
但后来又有机器报此问题,还是相同的原因,发现reset后至少17秒才成功,无脑的延时我觉得不可接受。以前听说,这是第一次使用ContentObserver。在reset前先设置SoundStyle,之后reset肯定会观察到sound_style的变化,此时再次设置SoundStyle,同时注销监听。