需求
HTC 510 Android手机上监控微信的PC端登陆请求界面(好绕口,其实就是pc上要登陆,需要手机端点验证界面)如下:
当出现这个界面时,点击登陆按钮。
分析
功能不复杂,分两步:
- 监控出现登陆界面
- 发出点击命令
监控界面使用service后台运行,定时查看当前界面是否是登陆界面。查看当前界面代码如下:
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.RunningTaskInfo info = manager.getRunningTasks(1).get(0);
String className = info.topActivity.getClassName(); //完整类名
Log.d(TAG, "className="+className);
if(className.equalsIgnoreCase("com.tencent.mm.plugin.webwx.ui.ExtDeviceWXLoginUI"))
{
Log.d(TAG, "action");
action.sendTap(235, 609);
}
自动点击登陆按钮代码如下:
public void init() {
try {
process = Runtime.getRuntime().exec("su");
outputStream = new PrintStream(new BufferedOutputStream(process.getOutputStream(), 8192));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendTap(int x, int y) {
// TODO Auto-generated method stub
if (!isValid()) {
return;
}
AsyncExec("input tap " + x + " " + y);
}
点击命令需要root权限。
这样基本代码已完成。it’s over?答案是肯定的。实际运行中,会发现service经常被干掉了。
守护雅典娜
如何守护service?
网上教程很多,大多数招都用了。并不能彻底解决,一旦内存吃紧,service就被停掉。
比如这些招:
1. service中重写onStartCommand方法,这个方法有三个返回值, START_STICKY是service被kill掉后自动
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
2. 配置android:persistent="true"
3. setForeground(true);
4. android:process=”com.xxx.xxxservice”配置到单独的进程中
以上的方法要么只是提升service优先级或者存活率。
最后还有一招也是最开始想到的一招,把应用作为系统应用。
应用系统化
系统应用都在system/app下,只要将应用放入此目录下就可以了。于是打个命令
adb push path/xx.apk system/app
然后呢,提示没有权限。是不是忘记打adb remount了呢。然too。
看来系统跟之前的不一样。 突然看到手机里有个Root Explorer应用,申请系统权限后可以操作system/app。so,曲线救国,
- 将xx.apk放入到sdcard中
- 用Root Explorer将xx.apk搬运到system/app中
然后adb reboot。
效果:后台程序稳定跑起来。
跑一会又发现问题,屏幕会灭掉,灭屏后微信不接收消息。同样包括登陆界面。
持久亮屏
如果是Activity,可以使用最新的两种亮屏手段:
一:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
二:
PowerManager powerManager = null; WakeLock wakeLock = null;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_1);
this.powerManager = (PowerManager) this .getSystemService(Context.POWER_SERVICE); this.wakeLock = this.powerManager.newWakeLock( PowerManager.FULL_WAKE_LOCK, "My Lock");
而后台只能用第二种。
ok,终于正常跑了。
开机自启动
使用广播监听,因为是系统应用
public void onReceive(final Context context, Intent intent) {
Log.d("BootReceiver action:",intent.getAction());
// if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent rootIntent = new Intent(context, RootService.class);
rootIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(rootIntent);
// context.startActivity(new Intent(context, MainActivity.class));
// }
}
<receiver android:name=".BootReceiver" >
<intent-filter android:priority="2147483647" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ALARM_ACTION" />
</intent-filter>
<intent-filter android:priority="2147483647" >
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
<data android:scheme="file" />
</intent-filter>
<intent-filter >
<action android:name="android.intent.action.PACKAGE_RESTARTED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
总结
开始本来想使用xposed做,但是刚xposed刚接触,短期内也没有解决思路。so最后使用常规应用解决。
非常规应用,耗电杠杠的。
守护雅典娜据说有大招叫双守护进程,微信上用的,有机会试试。