android 4.2 系统以后的飞行模式

项目中遇到了要控制飞行模式的功能,钻研了几天,终于解决。

解决过程中最大的问题是: android 4.2 之后 系统不予许第三方软件去设置飞行模式,除非你的app是系统应用,得到了root权限。  蛋疼~~

  网上大多数解决过程是 : 原文 http://blog.sina.com.cn/s/blog_69b5d2a50101fqze.html

   //获取当前的飞行模式状态  需要根据不同的Android版本进行修改

   @SuppressWarnings("deprecation")
   public boolean isAirplaneModeOn() 
   {
   //4.2以下
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) 
        {
              return Settings.System.getInt(getContentResolver(), 
                          Settings.System.AIRPLANE_MODE_ON, 0) != 0;              
       
        else //4.2或4.2以上
        {
              return Settings.Global.getInt(getContentResolver(), 
                          Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
        }    
   }
 
     //设置飞行模式
   @SuppressWarnings("deprecation")
   public void setAirplaneModeOn(boolean isEnable) 
   {  
   if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) 
        {
   Settings.System.putInt(getContentResolver(),  
                                       Settings.System.AIRPLANE_MODE_ON,isEnable ? 1:0);  
        }
   else //4.2或4.2以上 
        {
   Settings.Global.putInt(getContentResolver(), Global.AIRPLANE_MODE_ON, isEnable? 1 : 0);  
        }  
   Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);  
   intent.putExtra("state", isEnable);  
   sendBroadcast(intent); 
   }  
     需要注意的是,在4.2上其实App是没有权限修改Setting.Global的,解决办法是把你的App放到系统的system/app目录下,然后install。这样一来,App成为system app,可以获得写Setting.Global的权限。
 
 
   看看还需要把app变成系统应用,好像很麻烦,我是没有去研究把它变成系统应用。
  哎!网上去搜吧!  有人搜到stackoverflow上用adb shell 来解决:那 shell怎么去调用呢?
 
adb在终端执行的命令:
 
    第一种方法:
          
这是方法,添加到你的应用程序中即可,比较简陋,呵呵!
public void execShell(String cmd){
         try
             //权限设置
             Process p = Runtime.getRuntime().exec( "su" ); 
             //获取输出流
             OutputStream outputStream = p.getOutputStream();
             DataOutputStream dataOutputStream= new DataOutputStream(outputStream);
             //将命令写入
             dataOutputStream.writeBytes(cmd);
             //提交命令
             dataOutputStream.flush();
             //关闭流操作
             dataOutputStream.close();
             outputStream.close();
       
        catch (Throwable t) 
        
              t.printStackTrace(); 
             }
     }
 
 
第二种方式:
    
public void execCommand(String command) throws IOException {
     Runtime runtime = Runtime.getRuntime();
     Process proc = runtime.exec(command);
     try {
         if (proc.waitFor() != 0 ) {
             System.err.println( "exit value = " + proc.exitValue());
         }
         BufferedReader in = new BufferedReader( new InputStreamReader(
                 proc.getInputStream()));
         StringBuffer stringBuffer = new StringBuffer();
         String line = null ;
         while ((line = in.readLine()) != null ) {
             stringBuffer.append(line+ " " );
         }
         System.out.println(stringBuffer.toString());
 
     } catch (InterruptedException e) {
         System.err.println(e);
     } finally {
         try {
             proc.destroy();
         } catch (Exception e2) {
         }
     }
}

开关飞行模式的命令:

//开启飞行模式

settings put global airplane_mode_on 1

am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true

//关闭飞行模式settings put global airplane_mode_on 0

am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false

 

呵呵  安装apk之前,记得先把你的手机root哟 。

 

下面给出一片好文章,好学校的就是好:http://www.tanglei.name/blog/android-airplanemode-auto-switcher.html

UPDATE: 代码托管在GitHub上了, 欢迎有兴趣的童鞋加入一起完善。

之前写过一个Android手机根据时间设定自动切换飞行模式的代码,这次换了个屌丝红米手机之后安装后发现用不了。于是决定重新写一个。

整个功能要实现的话思路很清晰,只要改变一下系统配置(System.AIRPLANE_MODE_ON),发送一个通知即可。但发现Android的权限设置没有以前那么开放了。从Android 4.2开始(SDK API 17),设备的这些属性是只读的,官网上说:

Some device settings defined by Settings.System are now read-only. If your app attempts to write changes to settings defined in Settings.System that have moved to Settings.Global, the write operation will silently fail when running on Android 4.2 and higher.

所以对于Android4.2及其以上版本的手机来说就悲剧了~

刚开始在代码里面试图去修改System.AIRPLANE_MODE_ON 的属性,UI上貌似没有什么反映,log看到说缺少android.permission.WRITE_SECURE_SETTINGS 权限,在manifest里面声明,eclipse 又编译不过提示 Permission is only System Apps,说是必须得是系统应用才行。网上也有讨论各种解决方案,有说要写成系统应用,需要一个跟固件一起打包编译或者跟固件有相同的签名才行。同样也有人说通过反射可以实现。第一种方式应该很麻烦,得下某源码包编啊之类的,第二种方案有人说可以尝试下,但具体我也没试~不知道是否靠谱。

后来的后来,还是从网上找到了解决方案,不过device必须得root,不然没办法搞定。原文来自这里,虽然不知道是哪国语言~但代码还是认识。

//开启飞行模式
settings put global airplane_mode_on 1
am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true
//关闭飞行模式
settings put global airplane_mode_on 0
am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false

通过adb shell,输入以上两句命令,可以将切换飞行模式。核心问题解决了~剩下的就是需要通过Java代码去调用shell命令,这个不难~不过得注意需要通过root去调用,另外得防止程序卡死~

再后来在stackoverflow上也有人提到了这个解决方案,并且还给了另外一个解决方案,即通过sqlite去直接改变Android的系统配置。数据库位置在/data/data/com.android.providers.settings/databases/settings.db

sqlite3 /data/data/com.android.providers.settings/databases/settings.db
insert into global values(null, 'airplane_mode_on', 1); //相应的插入0值,即是取消飞行模式

当然上面的数据库修改之后要生效,还是必须得发上面的那个broadcast才能生效。

下面是我写的小程序的界面:

android自动切换飞行模式

使用方法如下:

  1. 分别设定好需要开启、关闭飞行模式的时间,默认情况下为凌晨12点30分开启飞行模式,早上7点关闭飞行模式。然后打开当前状态的按钮即可,打开后会提示下次切换飞行模式的时间。
  2. 设定的时间到之后,App会自动尝试去启用飞行模式状态,如上图第二副图所示,当然得允许了(最好添加到信任程序列表,不然每次弹框)。另外,设定的时间到之后,有可能你还正在使用手机而不想马上切换飞行模式,App会给你5s的时间考虑,5秒之后你没有操作,app就会自动启用飞行模式了。当然你取消之后,这次就不会切换了,不过当你通过按手机返回键(Home键不会)或者杀掉这个进程再重新启动这个App的时候,会根据时间设定满足规则则自动切换。
  3. 切换”关闭”状态即取消设定功能,若当前手机正处于飞行模式状态,也会切换为正常状态。

注意:针对Android4.2及其以上的版本,手机需要ROOT才OK,且建议添加到信任程序列表。4.2之前的版本是木有问题的。

欢迎有兴趣的同学下载1 下载2试用,有建议/意见欢迎留言反馈~

TODO:

  1. Android 各个版本UI风格的统一
  2. 增加多个时间段的设置,支持晚上睡觉和中午睡觉都转飞行模式,既省电又防打扰
  3. 自己写着瞎玩,应该有不少Bug

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值