Android 实现定时开关机另类实现--BSP级

来源:互联网 发布:java设计模式 编辑:程序博客网 时间:2024/05/19 03:22

前言:

条件,定时关机不能关机,只能待机;要能定时“开机”(唤醒)

1.定时“关机”(待机)

     众所周知android 有wakelock 在有wakelock 时不能待机,可按如下的方法进行待机;

    Java:

             启动force sleep 服务,只是运行force_sleep_part1.sh

            SystemProperties.set("ctl.start", "force_sleep");

     init.xxx.rc

定义force_sleep服务

            service force_sleep /system/bin/force_sleep_part1.sh
         oneshot                                           
         disabled


       force_sleep_part1.sh 

           切换root 运行force_sleep_part2.sh

      su -s /bin/sh /system/bin/force_sleep_part2.sh

      force_sleep_part2.sh 

          强制写/sys/power/state 来进行待机

      echo mem > /sys/power/state

2.定时“开机” (唤醒)

    此处折磨了我两天,终于在一个朋友的指点下找到原因。

    NOTE:  在有的厂商会控制通过RTC唤醒机器的程序,比如本人开发的这个平台会根据包名判断此包名内的程序是否在唤醒机器白名单内,每个厂商可能在不同的位置控制,碰到这个问题,不要一味的找自己写的代码的问题,还是要相信自己的。查下相关的流程,看下是否在哪修改掉了;比如在我使用的BSP中

frameworks/base/services/java/com/android/server/AlarmManagerService.java

608     private static final String[] sAlarmWhiteList = {609         "com.android.providers.calendar",610         "com.android.alarmclock",611         "com.android.deskclock",612         "com.android.keyguard",                          614     };
 616     /*  617      * Only packages above can set RTC_WAKEUP/ELAPSED_REALTIME_WAKEUP alarm. 618      */ 619     private int filterType(int type, PendingIntent operation) { 620         if( type == AlarmManager.RTC_WAKEUP || type == AlarmManager.ELAPSED_REALTIME_WAKEUP  ) { 621             String pakeageName = operation==null?null:operation.getTargetPackage(); 622             for(String packet : <strong><span style="color:#ff0000;">sAlarmWhiteList</span></strong>) { 623                 Slog.v("kevin", "packagename = "+ pakeageName); 624                 if( packet.equals(pakeageName) ) { 625                     return type; 626                 } 627             } 628             type = (type == AlarmManager.RTC_WAKEUP ) ? AlarmManager.RTC : AlarmManager.ELAPSED_REALTIME; 629         } 630         return type; 631     }    
 

AlarmManager 使用比较简单,但因为上面的原因,让我反复查了几十遍;

如下:

Calendar c = Calendar.getInstance();int length = timeonArray.length;c.set(Calendar.YEAR, timeonArray[0]);c.set(Calendar.MONTH, timeonArray[1] -1 );c.set(Calendar.DAY_OF_MONTH, timeonArray[2]);c.set(Calendar.HOUR_OF_DAY, timeonArray[3]);c.set(Calendar.MINUTE, timeonArray[4]);c.set(Calendar.SECOND, 0);c.set(Calendar.MILLISECOND, 0); Intent  PowerOnIntent = new Intent();PowerOnIntent.setAction(DataObject.ACTION_ALARM_POWER_ON_TIMER_OUT);PowerOnIntent.setClass(mContext, BroadcastReciver.class);mPowerOnPendingIntent = PendingIntent.getBroadcast(mContext,                0, PowerOnIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);if (isKitKatOrLater()) {mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), mPowerOnPendingIntent);} else {mAlarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), mPowerOnPendingIntent);}


就如上的代码就OK了。

3.android 重启

CommonUntils.ShellCommand("reboot");
Intent rebootIntent = new Intent(Intent.ACTION_REBOOT);
rebootIntent.putExtra("nowait", 1);
rebootIntent.putExtra("interval", 1);
rebootIntent.putExtra("window", 0);
mContext.sendBroadcast(rebootIntent);

基本上,按如上的方法,定时“开关”(待机,唤醒)机是没有任何问题的。


0 0