Android5.0以上系统的移动网络开关
来源:互联网 发布:linux socket 编程 编辑:程序博客网 时间:2024/04/29 08:57
Android5.0以上系统的移动网络开关,有需要的朋友可以参考下。
笔者最近遇到一个非常有意思的bug,贴出来和大家分享下。
那是一个温暖的早晨,阳光晒得人很舒服。一封bug邮件像一片叶子飘到我的邮箱。
一番交流,笔者确认负责的Widget开关在Android5.0以上系统没有作用。相信很多做过移动网络开关的朋友都知道,传统的方法是在ConnectivityManager中通过反射两个方法setMobileDataEnabled和getMobileDataEnabled来控制移动网络开和关的。
/** * Gets the value of the setting for enabling Mobile data. * * @return Whether mobile data is enabled. * @hide */ public boolean getMobileDataEnabled() { try { return mService.getMobileDataEnabled(); } catch (RemoteException e) { return true; } } /** * Sets the persisted value for enabling/disabling Mobile data. * * @param enabled Whether the mobile data connection should be * used or not. * @hide */ public void setMobileDataEnabled(boolean enabled) { try { mService.setMobileDataEnabled(enabled); } catch (RemoteException e) { } }
但是打开5.0以上的源码,这两个方法已经不存在了。
推荐一个不错的在线看源码的网站。在线源码网址。
此时老大的提醒帮了我,我打开5.0以上代码的TelephonyMananger类尝试通过反射获取setDataEnabled和getDataEnabled类完成操作。
源码
/** @hide */ @SystemApi public void setDataEnabled(boolean enable) { try { getITelephony().setDataEnabled(enable); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#setDataEnabled", e); } } /** @hide */ @SystemApi public boolean getDataEnabled() { try { return getITelephony().getDataEnabled(); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#getDataEnabled", e); } return false; }
我的反射方法:
public void setMobileDataState(Context cxt, boolean mobileDataEnabled) { TelephonyManager telephonyService = (TelephonyManager) cxt.getSystemService(Context.TELEPHONY_SERVICE); try { Method setMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("setDataEnabled", boolean.class); if (null != setMobileDataEnabledMethod) { setMobileDataEnabledMethod.invoke(telephonyService, mobileDataEnabled); } } catch (Exception e) { LogHelper.v(TAG, "Error setting" + ((InvocationTargetException)e).getTargetException() + telephonyService); }}public boolean getMobileDataState(Context cxt) { TelephonyManager telephonyService = (TelephonyManager) cxt.getSystemService(Context.TELEPHONY_SERVICE); try { Method getMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("getDataEnabled"); if (null != getMobileDataEnabledMethod) { boolean mobileDataEnabled = (Boolean) getMobileDataEnabledMethod.invoke(telephonyService); return mobileDataEnabled; } } catch (Exception e) { LogHelper.v(TAG, "Error getting" + ((InvocationTargetException)e).getTargetException() + telephonyService); } return false;}
但是报了InvocationTargetException错误。通过:
((InvocationTargetException)e).getTargetException()
方法得知是执行反射执行时发生如下错误:
Error settingjava.lang.SecurityException: Neither user 10240 nor current process has android.permission.MODIFY_PHONE_STATE.android.telephony.TelephonyManager
这个时候老大提醒我把APP移动到system/app下试试。
几番尝试,仍是同样的结果。
这个时候一个我无意的操作,将APP移动到system/priv-app,竟然成功了。在这个目录下,开关又可以重新工作了。
当然,我们的应用不可能装在这个目录下,只能采取折中的方案。但整个过程还是很开心的,这个bug算是我第一次发现了不同Android版本之间源码的差异,感觉很有意思。希望对大家有所启发。
转载地址:http://www.aichengxu.com/view/63324
0 0
- Android5.0以上系统的移动网络开关
- Android5.0以上系统的移动网络开关
- Android 5.0以上移动网络开关
- Android 5.0以上移动网络开关
- android5.0以上获取系统进程信息
- Android5.0以上WebView的兼容问题
- Android5.0及以上系统WebView上传图片遇到的那些坑
- Android5.0以上版本对比
- Android5.0系统的优缺点
- Android5.0以上app进程保活的正确姿势
- Android5.0以上沉浸式状态栏的问题
- Android5.0以上获取正在运行的应用
- android 控制移动网络开关
- Android5.0以上使用XUtils访问网络出现错误: java.io.IOException: stack size 1036KB
- Android异常-android5.0以上网络请求失败-retry error, curr request is null
- android5.0以上webview无法播放腾讯优酷等网络视频
- Android5.0以上通知栏图标设计
- android5.0以上获得所有进程
- Hadoop安装部署
- Adroid开发去掉标题栏ActionBar
- JAVA基础教程汇总
- Android Fragment详解(五):Fragment与Activity之间的通讯
- gson的一些相关问题
- Android5.0以上系统的移动网络开关
- MD5摘要算法
- maven依赖
- DIV相关的操作总结
- java学习之reflection反射
- Java中的堆和栈(百度)
- setTitleTextAttributes
- 首席信息安全官的未来将何去何从?
- sqlzoo练习答案--SELECT from Nobel Tutorial/zh