5.0上禁用手机移动数据上网调研
2016-03-22 18:22
267 查看
背景:
在4.4以及之前的手机,可以通过反射调用ConnectivityManager#setMobileDataEnabled()设置手机是否允许使用手机流量上网。
而到了5.0+,这个API已经被移除了。主要就是为了调研在5.0上如何实现,算是一个小调研吧。
调研结果:
在5.0上,取而代之的是TelephonyManager#setDataEnabled(),并且需要系统签名才能实现。
对应的API:
TelephonyManager Service是在com.android.phone这个进程中实现的,
具体的实现源码:
enforceModifyPermission()这个函数会检查掉调用者是否有MODIFY_PHONE_STATE权限。
这个权限的申明如下:
这也是造成我们需要系统签名的原因。
对比看了4.4的源码,它检查的是一个普通的权限:CHANGE_NETWORK_STATE:
最后,集成后的代码:
在4.4以及之前的手机,可以通过反射调用ConnectivityManager#setMobileDataEnabled()设置手机是否允许使用手机流量上网。
而到了5.0+,这个API已经被移除了。主要就是为了调研在5.0上如何实现,算是一个小调研吧。
调研结果:
在5.0上,取而代之的是TelephonyManager#setDataEnabled(),并且需要系统签名才能实现。
对应的API:
/** @hide */ @SystemApi public void setDataEnabled(boolean enable) { try { getITelephony().setDataEnabled(enable); }catch (RemoteException e){ Log.e(TAG, "Error calling ITelephony#setDataEnabled", e); } }
TelephonyManager Service是在com.android.phone这个进程中实现的,
具体的实现源码:
83 public class PhoneInterfaceManager extends ITelephony.Stub { ............... 1937 public void setDataEnabled(int subId, boolean enable) { 1938 enforceModifyPermission(); 1939 int phoneId = mSubscriptionController.getPhoneId(subId); 1940 log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 1941 Phone phone = PhoneFactory.getPhone(phoneId); 1942 if (phone != null){ 1943 log("setDataEnabled: subId=" + subId + " enable=" + enable); 1944 phone.setDataEnabled(enable); 1945 }else{ 1946 loge("setDataEnabled: no phone for subId=" + subId); 1947 } 1948 } ...............*
enforceModifyPermission()这个函数会检查掉调用者是否有MODIFY_PHONE_STATE权限。
这个权限的申明如下:
<permission android:name="android.permission.MODIFY_PHONE_STATE" android:permissionGroup="android.permission-group.PHONE_CALLS" android:protectionLevel="signature|system" android:label="@string/permlab_modifyPhoneState" android:description="@string/permdesc_modifyPhoneState"/>可以它这个权限是一个系统级的权限,也就是需要android:sharedUserId="android.uid.system"之后才能使用。
这也是造成我们需要系统签名的原因。
对比看了4.4的源码,它检查的是一个普通的权限:CHANGE_NETWORK_STATE:
对比看一下4.4上的禁用实现: public void setMobileDataEnabled(boolean enabled){ ....... enforceChangePermission(); ............... } private void enforceChangePermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService"); }
1679 <permission android:name="android.permission.CHANGE_NETWORK_STATE" 1680 android:permissionGroup="android.permission-group.NETWORK" 1681 android:protectionLevel="normal" 1682 android:description="@string/permdesc_changeNetworkState" 1683 android:label="@string/permlab_changeNetworkState" />*
最后,集成后的代码:
public boolean setMobileDataEnable(boolean enable) { //5.0以上,禁用移动网络使用TelephonyManager#setDataEnabled //5.0以下,则是ConnectivityManager#setMobileDataEnabled Object object = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getSystemService(TELEPHONY_SERVICE) : getSystemService(Context.CONNECTIVITY_SERVICE); String methodName = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? "setDataEnabled" : "setMobileDataEnabled"; Method setMobileDataEnable; try { setMobileDataEnable = object.getClass().getDeclaredMethod(methodName, boolean.class); setMobileDataEnable.setAccessible(true); setMobileDataEnable.invoke(object, enable); return true; } catch (Exception e) { NLog.d(TAG, "[setMobileDataEnable] error,exception:" + e.toString()); e.printStackTrace(); return false; } }
相关文章推荐
- Android代码混淆之混淆规则
- Java网络编程之Socket与SocketServer
- Spring Security(13)——session管理
- vim 复制到系统剪切板 VS 系统剪切板粘贴到vim
- 【POJ 3140】 Contestants Division(树型dp)
- 论大型项目的计划与监控(大纲)
- 【Unity3D游戏开发】定制新建C#文件的头描述 (三三)
- iOS7以后,sizeWithFont方法被弃用。
- CLUSTER集群Keepalived热备+LVS服务
- eclipse 要装tomcat时没有server选项
- android 开发工具
- 配置DB2的数据库ODBC连接
- Windows环境编译Hadoop 2.7.2
- c# 学习之一:编码约定
- 转:http2的资料与使用
- socket的半包,粘包与分包的问题
- matlab图像处理函数小结
- Java连接Oracle 10g数据库
- hadoop运行任务
- 数据结构学习笔记02堆栈