ContentObserver通过监听database来实现GPRS快捷开关
改变GPRS的开和关的状态我们一般调用反射就可以,如下:
public static boolean isMobileDataEnable(Context context) {//判断是否打开 boolean mobileDataEnabled = false; // Assume disabled ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); try { Class cmClass = Class.forName(cm.getClass().getName()); Method method = cmClass.getDeclaredMethod("getMobileDataEnabled"); method.setAccessible(true); // Make the method callable // get the setting for "mobile data" mobileDataEnabled = (Boolean) method.invoke(cm); } catch (Exception e) { e.printStackTrace(); } return mobileDataEnabled; } public static void setMobileDataEnabled(Context context, boolean enabled) {//开和关 try { final ConnectivityManager conman = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); final Class conmanClass = Class .forName(conman.getClass().getName()); final Field connectivityManagerField = conmanClass .getDeclaredField("mService"); connectivityManagerField.setAccessible(true); final Object connectivityManager = connectivityManagerField .get(conman); final Class connectivityManagerClass = Class .forName(connectivityManager.getClass().getName()); final Method setMobileDataEnabledMethod = connectivityManagerClass .getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); setMobileDataEnabledMethod.setAccessible(true); setMobileDataEnabledMethod.invoke(connectivityManager, enabled); } catch (ClassNotFoundException e) { e.printStackTrace(); tryToSetMobileDataEnabled(context, enabled); } catch (NoSuchFieldException e) { e.printStackTrace(); tryToSetMobileDataEnabled(context, enabled); } catch (IllegalAccessException e) { e.printStackTrace(); tryToSetMobileDataEnabled(context, enabled); } catch (NoSuchMethodException e) { e.printStackTrace(); tryToSetMobileDataEnabled(context, enabled); } catch (InvocationTargetException e) { e.printStackTrace(); tryToSetMobileDataEnabled(context, enabled); } }
注意,我们通过点击开关改变了GPRS的状态,视图是不是也要跟着变化,比如你的chackbutton,或者button,我们依据什么来改变状态呢?
上网搜一搜,发现改变了状态之后会接受系统的ConnectivityManager_Change广播,ConnectivityManager可以判断状态,实际上通过系统广播来改变你的Button状态实际上是不靠谱的事情。
因为 :
1.网络状态不单单是Gprs,还有wifi,上面的提到的广播在wifi发生改变的时候也会接收到,再加上wifi也有一堆广播,,经过实际实践,用广播来改变状态简直一团糟。
2.广播有延时,你 的Button的状态如果改变有延时的话,会给人一种卡卡的感觉,觉的你的app好卡啊。
上面的问题在使用ContentObserver之后统统不用考虑了,Observer:观察者的意思。
如下,我们看ContentObserver怎么用
重写ContentObserver类,重写onChange方法:
class MyMobileDataObserver extends ContentObserver { Context context; public MyMobileDataObserver(Context context, Handler handler) { super(handler); this.context = context; } @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub super.onChange(selfChange); Log.i("TAG","database has change"); } }
MyMobileDataObserver dataObserver = new MyMobileDataObserver(this, new Handler()); getContentResolver().registerContentObserver( Settings.Secure.getUriFor("mobile_data"), false, dataObserver);//"moblie_data"参数表示观察移动数据状态变化当你调用反射去改变GPRS数据的时候,MyMobileDataObserver 的onCHange立刻就有了相应,你就可以在onChange方法中去跟新你的试图界面了。
ContentObserver监听的是你的手机的数据库,需要一个Uri标识符,这样就可以监听你Uri下的数据库了,包括表,记录都可以。