普通APP如何使得系统休眠
来源:互联网 发布:小企业的会计软件 编辑:程序博客网 时间:2024/06/06 19:57
- 引言
- lockNow函数的作用
- 普通APP如何使得系统休眠
- 普通APP如何成为device admin
- 结束语
引言
Android 系统休眠,常见的接口是PowerManager提供的goToSleep,但是很遗憾,调用这个接口需要System 权限;即用Platform key签名的APP才可以;
那么普通APP 可否使得系统suspend呢?
lockNow函数的作用
lockNow定义于文件DevicePolicyManager.java中,实现如下:
mService即IDevicePolicyManager,由DevicePolicyManagerService实现;
public void lockNow() { if (mService != null) { try { mService.lockNow(); } catch (RemoteException e) { Log.w(TAG, "Failed talking with device policy service", e); } } }
mService即IDevicePolicyManager,由DevicePolicyManagerService实现;
所以lockNow的具体实现在DevicePolicyManagerService中
public void lockNow() { if (!mHasFeature) { return; } synchronized (this) { // This API can only be called by an active device admin, // so try to retrieve it to check that the caller is one. getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_FORCE_LOCK); lockNowUnchecked(); }}private void lockNowUnchecked() { long ident = Binder.clearCallingIdentity(); try { // Power off the display mPowerManager.goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0); // Ensure the device is locked new LockPatternUtils(mContext).requireCredentialEntry(UserHandle.USER_ALL); getWindowManager().lockNow(null); } catch (RemoteException e) { } finally { Binder.restoreCallingIdentity(ident); } }
getActiveAdminForCallerLocked检查当前的调用者是否为Device admin,如果是的,则执行lockNowUnchecked,否则会在getActiveAdminForCallerLocked执行过程中抛出SecurityException;
而lockNowUnchecked函数实际上调用了goToSleep使得系统suspend;
总的来说,lockNow是对goToSleep降低权限的封装,所以我们可以通过调用lockNow来实现系统suspend
普通APP如何使得系统休眠
在Android系统中,APP根据签名不同分为system app或者普通app,system app使用platform key签名,具备system权限,可以做一些系统级别的操作,例如调用goToSleep,调用reboot等;普通APP即用没有用哦platform key签名的app;那么这样的APP 如何实现系统休眠呢?我们刚刚提到的lockNow函数就是一种办法;但是问题是,嗲用lockNow之前得先具备device admin权限;
普通APP如何成为device admin
1.. 在AndroidManifest.xml中添加receiver类继承自DeviceAdminReceiver
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.suspendappnormal.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name="com.example.suspendappnormal.MyAdmin" android:label="@string/app_name" android:permission="android.permission.BIND_DEVICE_ADMIN" > <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver> </application>
MyAdmin即为添加的receiver
2.. 为MyAdmin添加java code
package com.example.suspendappnormal;import android.app.admin.DeviceAdminReceiver;public class MyAdmin extends DeviceAdminReceiver {}
很简单,就是一个继承自DeviceAdminReceiver的类,不用实现任何函数
3.. 在Activity中实现device admin的添加
activity_main.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.suspendappnormal.MainActivity" > <Button android:id="@+id/admin_add_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="AddToAdminDevice"/> <Button android:id="@+id/suspend_btn" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="suspend"/></LinearLayout>
id 为admin_add_btn的button,做 device admin的添加,如果添加成功之后,该按钮编程灰色,不可点击;如果已经具备device admin权限,该按钮也是灰色,不可点击;
id为suspend_btn的Button,完成lockNow函数的执行;
onCreate函数
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAdminName = new ComponentName(this, MyAdmin.class); mDm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); mAdminAddBtn = (Button)findViewById(R.id.admin_add_btn); mAdminAddBtn.setOnClickListener(this); mSuspendBtn = (Button)findViewById(R.id.suspend_btn); mSuspendBtn.setOnClickListener(this); if (!mDm.isAdminActive(mAdminName)) { mAdminAddBtn.setEnabled(true); } else { mAdminAddBtn.setEnabled(false); } }
new 出mAdminName的component组件,就是为该组件所在的process添加admin权限;
点击AddToAdminDevice button,则添加admin权限,button的click相应事件如下:
@Override public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()) { case R.id.admin_add_btn: if (mDm != null) { if (!mDm.isAdminActive(mAdminName)) { Log.i(TAG, "has no admin, add it"); Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); intent.putExtra (DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName); intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "sara sara sara"); startActivityForResult(intent, 0); mAdminAddBtn.setEnabled(false); } } break; case R.id.suspend_btn: if (mDm != null) { if (mDm.isAdminActive(mAdminName)) { Log.i(TAG, "lockNow"); mDm.lockNow(); } else { Log.i(TAG, "admin not active"); } } break; default: break; } }
4.. 运行效果如下:
第一次运行该APP时:
点击ADDTOADMIN button
点击Active
此时ADDTOADMIN button是disable的,因为此时APP已经获得了admin权限;
点击Suspend即会使得系统suspend
结束语
device admin权限,只用申请一次,该APP就一直拥有,所以不用每次调用lockNow时,都去为该APP申请;
此外Android系统中,admin权限的管理在Setting app中;
Setting->security->Device Adminstrators;
如果要删除具备admin权限的APP,需要先到Setting中,将该权限移除;否则无法删除该APP;
- 普通APP如何使得系统休眠
- Android 普通APP APK 如何确认系统是MTK 平台
- 如何让系统充电时不休眠
- Win7系统笔记本如何实现关盖不休眠
- 电脑待机与休眠区别,XP系统如何进入休眠状态
- 如何防止启动的后台Service在系统休眠的情况下不被休眠
- win8.1系统中如何实现休眠下不断网
- Android Kitkat 如何让系统永久不休眠
- 普通开发者如何吃到企业级APP这块大蛋糕?
- 微图App中如何切换普通标注和专业标注
- 系统定时休眠
- 禁用系统休眠
- CentOS 7 休眠系统
- 防止Android系统休眠
- qt 屏蔽系统休眠
- Android 系统永不休眠
- 避免系统休眠后线程休眠
- mobile 如何防止休眠
- 错误信息:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
- android动态修改应用图标和应用名称
- 今年多少岁
- JAVA学习47_在Eclipse下,出现“找不到或无法加载主类 ”的问题的解决方式
- Maven学习详解(10)——Maven常用命令大全与pom文件讲解
- 普通APP如何使得系统休眠
- 深度神经网络在图像识别应用中的演化【笔记】
- 最小生成树Prim算法
- Spring3中js/css/jpg/gif等静态资源无法找到(No mapping found for HTTP request with URI)问题解决
- 僵尸进程和孤儿进程
- js 正则验证手机号
- [Pandas] 10分钟Pandas之旅 01
- 感染病毒WannaCry? 信息安全有华胜信泰
- 错误:argument of type "char *" is incompatible with parameter of type "LPCWSTR"