Android进入suspend状态(goToSleep)

Android有个很有趣的现象,公开的API把系统进入suspend的功能移除了,开发者想让Android机器进入suspend状态,必须使用reflect机制(这种感觉,极为类似N多年前有一本书专门介绍Windows未公开的API )。

不明白Google为什么这么做,唯一的猜测,是为了安全考虑。但是,对于某些应用场景,还是需要程序控制Suspend/resume的。

下面简单介绍其使用,

1. 如果需要使用suspend/resume功能,需要在AndroidManifest.xml声明获得“DEVICE_POWER”权限和系统权限,示例代码如下,

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testsuspend"
    android:sharedUserId="android.uid.system">

    <application
        ...
    </application>

    <uses-permission android:name="android.permission.DEVICE_POWER" />

</manifest>

 2. 仅仅声明权限是不够的,要想拥有system权限,还需要sign,每一款产品的sign key都不一样,这就造成,即使可以在某一款产品上运行,在其他产品上也是无法运行的(需要使用该产品的sign key重新sign)。

另外,还有一种方法,直接把apk push到文件夹“/system/priv-app/”下,这种方法我没有尝试,我一般使用sign key的方式。

adb remount
adb push  xxx.apk  /system/priv-app/
adb reboot 

3. 下面是代码实现部分,仅供参考,

进入suspend/sleep的代码段如下,

public static void goToSleep(Context context) {
        PowerManager powerManager= (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        try {
            powerManager.getClass().getMethod("goToSleep", new Class[]{long.class}).invoke(powerManager, SystemClock.uptimeMillis());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
}

屏幕唤醒的代码段如下,

    public static void wakeUp(Context context) {
        PowerManager powerManager= (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        try {
            powerManager.getClass().getMethod("wakeUp", new Class[]{long.class}).invoke(powerManager, SystemClock.uptimeMillis());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

4. 如果不使用上面的reflect方法,还有没有其他方法?

据我所查,还有一种不是特别好的方法,即降低SDK版本到20以下,需要做如下更改,

4.1 build.gradle中请指定SDK版本为20以下,参考如下代码,注意“compileSdkVersion”已经更改为20,

apply plugin: 'com.android.application'

android {
    compileSdkVersion 20
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.example.suspendresume"
        minSdkVersion 14
        targetSdkVersion 17
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    
}

4.2 请在AndroidManifest.xml声明获得“DEVICE_POWER”权限和系统权限, 安装apk前需要sign。

4.3 不使用reflect方式的参考代码如下,

	private static void enterSuspend(Context context){
        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        pm.goToSleep(SystemClock.uptimeMillis());
	}

5. 如果有该平台的BSP代码,也可以把自己的代码放到BSP中编译,然后直接包进system image,会省去reflect和sign的动作,不过debug稍微麻烦。

好了,关于奇怪的goToSleep就分享这么多,希望能为有需要的童鞋提供帮助。

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值