在编写Android应用时由于模拟器速度慢等原因多数使用真机进行调试,但将手机插到电脑上有很多时候也只是为了充电,因此在Android开发设置中将屏幕设为保持唤醒状态也不太好,因此想不开启保持唤醒状态,而是在真机调试时自动点亮屏幕,由于刷了CyanogenMod的系统,因此想到了利用修改源码的方式实现。
在Eclipse中修改Android工程后进行调试会安装新的apk到真机,
/frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java中会收到安装这一消息,
public static void main(String[] args) {
new Pm().run(args);
}
其中args参数中包含了传来的命令是安装还是卸载或其它任务,
String op = args[0];
mNextArg = 1;
if ("list".equals(op)) {
runList();
return;
}
if ("path".equals(op)) {
runPath();
return;
}
if ("install".equals(op)) {
runInstall();
return;
}
if ("uninstall".equals(op)) {
runUninstall();
return;
}
if ("clear".equals(op)) {
runClear();
return;
}
如果为安装则执行runInstall(),调用PackageManagerService进行安装,
mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags,
installerPackageName);
PackageManagerService位于/frameworks/base/services/java/com/android/server目录下,installPackage()准备开始安装apk,每次修改了程序调试时新的apk安装都会调用到这一函数,因此在这一函数的开头加上一句发送Broadcast消息给解锁服务(先解锁后点亮屏幕),
sendPackageBroadcast(Intent.ACTION_PACKAGE_INSTALL_START, null, null, null, null);
sendPackageBroadcast是PackageManagerService中封装好的一个发送Broadcast的函数,
Intent.ACTION_PACKAGE_INSTALL_START是我在Intent中手动加的一条字符串,表明准备开始安装apk。
接下来到/frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewMediator,
KeyguardViewMediator对锁屏/解锁进行调度,里面已经有了mBroadCastReceiver来接收消息,直接使用此BroadcastReceiver,添加消息处理,
if (action.equals(Intent.ACTION_PACKAGE_INSTALL_START)) {
Log.d(TAG, "ACTION_PACKAGE_INSTALL_START");
mHandler.sendEmptyMessage(HIDE); // 解锁
pokeWakelock(120000); // 点亮屏幕
}
添加消息注册,
filter.addAction(Intent.ACTION_PACKAGE_INSTALL_START);
这样,只要每次修改了程序后进行调试便会自动点亮屏幕。调试时会安装新的apk,安装时发送ACTION_PACKAGE_INSTALL_START消息,被KeyguardViewMediator接收,接收后解锁屏幕,点亮屏幕。
最后make framework && make android.policy && make services编译生成修改后的jar包,替换掉手机中原来的jar包就行了。
不足之处:要修改了工程才能点亮屏幕,也就是要有安装apk的动作,直接对最新已装的apk进行调试无效。
参考:http://hi.baidu.com/minisky/blog/item/2ab4ea19d6652c73dbb4bd08.html
http://blog.csdn.net/lizhiguo0532/article/details/7077432
http://helin-era.iteye.com/blog/969930