Android 自动休眠唤醒

本文介绍了Android系统中自动休眠唤醒的实现,包括Linux的休眠步骤、Android的Wake_Lock、Early_Suspend和Late_Resume机制。通过读写`/sys/power/state`文件可以控制休眠,而PowerManagerService的goToSleep系列方法则在应用层触发这一过程。在系统启动时,main_wake_lock保持系统不休眠,释放此锁则允许系统进入睡眠状态。项目实践中,可通过广播接收器和服务来实现自动开关机功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天研究的内容:
**一、自动休眠唤醒的实现.
二、binder机制.(广播既然能实现进程间通信,两者区别?)
三、自定义控件的使用和原理.(benwenbutantao….)
四、动画效果的实现原理.**

一、自动休眠唤醒的实现.
分析:
标准Linux睡眠唤醒机制简介:
在标准Linux中,休眠主要分三个主要的步骤:(1)冻结用户态进程和内核态任务;(2)调用注册的设备的suspend的回调函数,其调用顺序是按照驱动加载时的注册顺序。(3)休眠核心设备和使CPU进入休眠态冻结进程是内核把进程列表中所有的进程的状态都设置为停止,并且保存下所有进程的上下文。 当这些进程被解冻的时候,它们是不知道自己被冻结过的,只是简单的继续执行。
那么是如何让Linux进入休眠的呢?其实很简单,因为Android和kernel已经做了很多复杂的工作,所以用户只需可以通过读写sys文件/sys /power/state 就可以实现控制系统进入休眠。
比如: #echo mem > /sys/power/state /////// 使系统进行睡眠

    #echo  on   > /sys/power/state////////////使系统从睡眠中唤醒过来

当然还有其它的状态操作,在下面的内容中将有介绍。

Android睡眠唤醒机制简介:

Android在Linux内核原有的睡眠唤醒模块上基础上,主要增加了下面三个机制:

Wake _Lock 唤醒锁机制;

Early _Suspend 预挂起机制;

Late _Resume 迟唤醒机制;

其基本原理如下:
当启动一个应用程序的时候,它都可以申请一个wake_lock唤醒锁,每当申请成功之后都会在内核中注册一下(通知系统内核,现在已经有锁被申请),当应用程序在某种情况下释放wake_lock的时候,会注销之前所申请的wake_lock。特别要注意的是:只要是系统中有一个wake_lock的时候,系统此时都不能进行睡眠。但此时各个模块可以进行early_suspend。当系统中所有的wake_lock都被释放之后,系统就会进入真正的kernel的睡眠状态。在系统启动的时候会创建一个主唤醒锁main_wake_lock,该锁是内核初始化并持有的一个WAKE_LOCK_SUSPEND属性的非限时唤醒锁。因此,系统正常工作时,将始终因为该锁被内核持有而无法进入睡眠状态。也就是说在不添加新锁的情况下,只需将main_wake_lock 解锁,系统即可进入睡眠状态。
这里写图片描述
源代码的实现为:
PowerManager.java goToSleep( )
PowerManagerService.java goToSleep()
PowerManagerService.java goToSleepWithReason()
PowerManagerService.java setPowerState()
PowerManagerService.java SetScreenStateLocked ()
Power.java setScreenState()
android_os_Power.cpp setScreenState()
power.c set_screen_state( )
main.c state_store( )
项目中的逻辑为:
1.发出广播,由助手来实现自动开关机。

// 保存信息
            SharedPrefrenceUtil.saveData(activity,
                    SplashActivity.CONNECTER_INFO, ConnecterInfo.getInstance());

            Intent intent = new Intent();
            intent.setAction("R2KTIMEMACHINESENDER");
            String time = ConnecterInfo.getInstance().getTime();
            if (isSleepInable) {
                if (time != null && time.length() != 0 && time.contains("#")) {
                    String times[] = time.split("#");
                    intent.putExtra("timeOnHour", Integer.parseInt(times[0].split(":")[0]));
                    intent.putExtra("timeOnMin", Integer.parseInt(times[0].split(":")[1]));
                    intent.putExtra("timeOffHour", Integer.parseInt(times[1].split(":")[0]));
                    intent.putExtra("timeOffMin", Integer.parseInt(times[1].split(":")[1]));
                }
            } 
            activity.sendBroadcast(intent);

2.助手收到广播后启动service并保存时间信息。

/*
<receiver android:name="com.example.zreceive.r2ktimemachine.TimeMachineBroReceiver"
                 >
            <intent-filter >
                <action android:name="R2KTIMEMACHINESENDER"/>
            </intent-filter>
        </receiver>
*/
public class TimeMachineBroReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        SharedPreferences sp = context.getSharedPreferences("TimeMachine",
                context.MODE_PRIVATE);
        Editor editor = sp.edit();
        Boolean isSleepInable = intent.getBooleanExtra("isSleepInable", false);
        int timeOnHour = intent.getIntExtra("timeOnHour", -1);
        int timeOnMin = intent.getIntExtra("timeOnMin", -1);
        int timeOffHour = intent.getIntExtra("timeOffHour", -1);
        int timeOffMin = intent.getIntExtra("timeOffMin", -1);
        editor.putInt("timeOnHour", timeOnHour);
        editor.putInt("timeOnMin", timeOnMin);
        editor.putInt("timeOffHour", timeOffHour);
        editor.putInt("timeOffMin", timeOffMin);
        editor.commit();
    }
}
//MainActivity 
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initlayout();

        /*
         * 启动自动开关机服务
         */
        Intent iJettyServiceIntent = new Intent(this, SleepTimerService.class);
        this.startService(iJettyServiceIntent);
    }

3.service执行自动开关机操作.

public class SleepTimerService extends Service {
    private WakeLock mWakeLock ;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        acquireWakeLock();
        new Thread(new LockScreenRunbale()).start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private class LockScreenRunbale implements Runnable {

        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(1000 * 50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int onTimeHour = 0;
                int onTimeMin = 0;

                int offTimeHour = 0;
                int offTimeMin = 0;

                SharedPreferences sp = getSharedPreferences("TimeMachine", MODE_PRIVATE);
                onTimeHour = sp.getInt("timeOnHour", -1);
                onTimeMin = sp.getInt("timeOnMin", -1);
                offTimeHour = sp.getInt("timeOffHour", -1);
                offTimeMin = sp.getInt("timeOffMin", -1);

                if (onTimeHour == offTimeHour && onTimeMin == offTimeMin) {
                    return;
                }
                if (isOnTime(onTimeHour, onTimeMin) || isOffTime(offTimeHour, offTimeMin)) {
                    // 触发POWER事件
                    execShell("input keyevent 26");
                }
            }
        }

    };

    public void execShell(String cmd) {
        try {
            // 权限设置
            Process p = Runtime.getRuntime().exec("sh");
            // 获取输出流
            OutputStream outputStream = p.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(
                    outputStream);
            // 将命令写入
            dataOutputStream.writeBytes(cmd);
            // 提交命令
            dataOutputStream.flush();
            // 关闭流操作
            dataOutputStream.close();
            outputStream.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }


    /**
     * 保持电源锁,防止系统进入休眠后关机
     */
    private void acquireWakeLock() {
        if (null == mWakeLock) {
            PowerManager pm = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"");
            if (null != mWakeLock) {
                mWakeLock.acquire();
            }
        }
    }

    //释放设备电源锁,目前未使用
    private void releaseWakeLock() {
        if (null != mWakeLock) {
            mWakeLock.release();
            mWakeLock = null;
        }
    }

    /**
     * 判断是否已经到关机时间
     * @param offTimeHour
     * @param offTimeMinute
     * @return
     */
    private boolean isOffTime(int offTimeHour, int offTimeMinute) {
        PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
        if (!pm.isScreenOn()) {
            return false;
        }
        Calendar c = Calendar.getInstance();//可以对每个时间域单独修改

        int hour = c.get(Calendar.HOUR_OF_DAY); 
        int minute = c.get(Calendar.MINUTE);

        if (hour == offTimeHour && minute == offTimeMinute) {
           return true;
        }
        return false;
    }

    /**
     * 判断是否已经到开机时间
     * @param onTimeHour
     * @param onTimeMinute
     * @return
     */
    private boolean isOnTime(int onTimeHour, int onTimeMinute) {
        PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
        if (pm.isScreenOn()) {
            return false;
        }
        Calendar c = Calendar.getInstance();//可以对每个时间域单独修改

        int hour = c.get(Calendar.HOUR_OF_DAY); 
        int minute = c.get(Calendar.MINUTE);

        if (hour == onTimeHour && minute == onTimeMinute) {
           return true;
        }
        return false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值