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版本号之间源代码的差异,感觉非常有意思。希望对大家有所启示。

时间: 2024-10-12 12:49:22

Android5.0以上系统的移动网络开关的相关文章

Android5.0系统的优缺点

Android L(5.0)正式定名为 Lollipop(棒棒糖).安卓已经六岁了,也总算有一次重大改观了.安卓5.0 Lollipop带来了全新的,扁平化的外观,更好的通知中心,重新设计的核心应用,并提升了在安卓设备上的性能表现--增加了一些以前所缺失的重要应用类别. 首先来看一下Android L相比之前的版本有什么新鲜的东西. 原文博客请参考:点击打开链接 一:自定义通知中心 Lollipop为用户带来了对通知中心前所未有的控制性,每一个应用程序都可以在通知中心进行单独的设置,并且只有在用

Android5.0网络之ipv6

移动设备的大量兴起势必进一步加强ip地址不足的危机.ipv6也许成为一种比较好的选择方案. ipv6地址的获取分为两种方式:无状态:有状态 无状态:通过接收路由公告(RA)来设置自己的ipv6地址 有状态:通过dhcpv6 server分发ipv6地址 Android5.0代码中,framework层对ipv6的支持已经没问题,native层仅仅提供了设置ipv6地址的接口. 对于无状态方式,kernel层就支持,只要收到RA,就会自动设置ipv6地址 对于有状态方式,Android5.0中的d

Android5.0 之一 概述

Android 5更新你的应用程序添加各种新功能,比如在锁屏通知,一个全新的相机API,OpenGL ES 3.1,新材料的设计界面,以及更多. 1 手机发展的过程 2 Linux发展的历史 3 智能手机平台简介 4 Android的诞生 5 Android的优势 手机发展的过程 1G手机--传说中的"大哥大"时代 1983年摩托罗拉推出了首款手机 型号:DynaTAC 8000X 重1公斤多 充电时间10小时,通话时间半小时 研发周期超过了10年 耗资超过1亿美元 摩托罗拉是最早进入

ubuntu 12.04(64位)下搭建android5.0开发环境

?? 本文介绍在WIN7操作系统通过在虚拟机VMWARE和Ubuntu下搭建了一个android5.0编译环境的操作过程,包括LINUX系统安装,JDK安装,samba服务和ssh服务安装.因为要下载补丁,需要网络支持,要能够上网.电脑要64位cpu,安装好win7操作系统. 第一步: 下载ubuntu地址:LINUX有3个版本,分别是server,desktop,alternateserver版本是没有图形界面服务器安装版本.alternate适合专业个性化定制安装版本,不推荐初学者用这个版本

android5.0中RecycleView的用法

最近学习了android5.0中新增的一个组件RecycleView,是用来代替当前的listview开发的,是因为在RecycleView中已经有了viewholder缓存,并且不同的item之间可以设置不同的布局.能非常有效地维护了意见数量有限,滚动大的数据集.使用 RecyclerView当你拥有的数据的集合,它的元素在运行时改变基于用户行为和网络事件的小部件 首先看看RecyclerView的一个小例子: 需要引入:android-support-v7-appcompat.jar and

android5.0视频教程下载

国内首部android 5.0视频教程 网盘下载地址: http://pan.baidu.com/s/1dDcoUUP 密码: zw67 要是网盘失效了,请加我QQ: 3113533060 课程内容 本套视频特点: 1.本套视频知识点覆盖率是市面上最广的.最有深度的,从入门到中级.到完成一个项目的全面应用讲解. 2.本套视频层次性很强.不像别的机构只是断章取义的推出视频,吊足学习者的胃口. 3.本套视频重点介绍了 1).Android概述: 2).Android集成开发环境搭建: 3).常用UI

如何吃好Android5.0棒棒糖

谷歌在安卓棒棒糖系统中的"改进"很容易让人眼前一亮,不过也有人认为其便捷的背后同时也带来了一些安全问题.提到安全,关于Android5.0,如何避免棒棒糖安全隐患,吃好Android5.0这颗棒棒糖? 如果你的设备使用了安卓棒棒糖(安卓5.0),为了设备安全,这里有些新的特性需要你去了解: 1. Smart Lock 很少有Android设备携带指纹识别,而Google添加了一些新方法使锁定和解锁设备更加容易. 棒棒糖的一个新的特性SmartLock,允许用户使用另个"Tru

Android5.0更新内容简介

2014/6/26 凌晨Google IO 2014大会准时开幕,在本次大会上可以说发布出很多项目,发布的产品非常少.那么重点介绍的当然是我们最新的Android 5.0系统,本次Android 5.0系统代号为Lollipop(棒棒糖),所以大家也很亲切的称呼它为Android L系统. 那么Android 5.0都做出哪些改变或是升级呢? 1.全新的Material Design设计语言:在新系统的界面变的更加趋于扁平化,不仅如此,这样趋于扁平化的设计也将会在所有的谷歌产品中体现出来; --

【适配整理】Android 7.0 调取系统相机崩溃解决android.os.FileUriExposedException

一.写在前面 最近由于廖子尧忙于自己公司的事情和 OkGo (一款专注于让网络请求更简单的网络框架) ,故让LZ 接替维护 ImagePicker(一款支持单.多选.旋转和裁剪的图片选择器),也是处理了诸多bug,最近总算趋于稳定了,这里就把Android N (API 24) 以上的相机适配方案分享给大家. Android Nougat 也是被更新很久了,作为一名 Andorid 开发者,我们有义务时刻准备自己调整 targetSdkVersion 为最近的一个,于是从之前的 23 直接提高到