您的位置:首页 > 其它

5.0上禁用手机移动数据上网调研

2016-03-22 18:22 267 查看
背景:

    在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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: