Android基于Socket无线遥控(一)-Socket基本模型搭建

http://233.io/article/1017992.html

本篇主要内容涉及模拟系统按键消息,单击事件,触屏事件等,模拟Android系统按键参考了网上资料(见引用1),无线遥控收发信息部分和上节所讲内容一样。 一、技术介绍 1.模拟按键及触屏相关 模拟按键和触摸屏需要调用SDK内部隐藏方法,在WindowManagerService中实现UI交互的注入方法,但可惜WindowManagerService这个类是被标记了@hide,外部不能使用,不然恶意程序就随意控制Android设备了。 在WindowManagerService类中,按键和触屏消息的方法如下: // Injects a keystroke event into the UI.
public boolean injectKeyEvent(KeyEvent ev, boolean sync){
...
}//  Inject a pointer (touch) event into the UI.
public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
...
}更进一步可以搜素相关资料,这里涉及到Binder,还有AIDL( Android接口描述语言),这些内容真要弄明白还需要花些时间,大概作用就是跨进程之间的数据通讯,Binder更是在Java层与C++层之间的数据传输起到很大作用。在Android源码中随处可见,因为实际项目中很少使用,之前看过的内容很快就忘记了。 WindowManagerService类就是IWindowManager.Stub的实现类,在内部程序中使用如下:
// 模拟触摸消息private static void sendPointerSync(MotionEvent event) {
try {
(IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectPointerEvent(event, true);
} catch (RemoteException e) {}
}// 模拟按键消息private static void sendKeySync(KeyEvent event) {
try {
(IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectKeyEvent(event, true);
} catch (RemoteException e) {}
}2.常见按键消息 Key  | Constant Value Back 4 Power 26 Menu 82 Home 3 Search 84 方向键: 上 19 下 20 左 21 右 22 确认(类似单击):23 音量键: 音量减 25 音量加 24 更详细的KeyEvent请点击:http://developer.android.com/reference/android/view/KeyEvent.html
二、为Android系统添加模拟按键对外接口 步骤一:在Android源码中传建新扩展模块目录 在源码的frameworks/base/cmds下传建一个文件夹,本例文件夹命名【analog_control】,在此目录下可存放用java或C编写的可运行程序。 步骤二:编写模拟按键相关代码 在步骤一所创建的目录下新建一个AnalogControl.java文件,编写程序代码,在此你可以使用IWindowManager类,本例需要模拟按键key,长按键keypress,点触笔touch,点触笔长按touchpress,以及移动move等。(本例代码使用引用1的代码)
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.IWindowManager;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.RemoteException;
import android.util.Log;
public class AnalogControl {public static void main(String args[])throws Exception{String[] mArgs = args;try{String opt = mArgs[0];if(opt.equals("touch")){float x = Float.valueOf(mArgs[1]);float y = Float.valueOf(mArgs[2]);MotionEvent e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0);sendPointerSync(e);e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0);sendPointerSync(e);}else if(opt.equals("move")){float x = Float.valueOf(mArgs[1]);float y = Float.valueOf(mArgs[2]);float x2 = Float.valueOf(mArgs[3]);float y2 = Float.valueOf(mArgs[4]);MotionEvent e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0);sendPointerSync(e);e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, x, y, 0);sendPointerSync(e);e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, x, y, 0);sendPointerSync(e);e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, x2, y2, 0);sendPointerSync(e);e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, x2, y2, 0);sendPointerSync(e);e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x2, y2, 0);sendPointerSync(e);}else if(opt.equals("key")){int keycode = Integer.valueOf(mArgs[1]);KeyEvent k = new KeyEvent(KeyEvent.ACTION_DOWN,keycode);sendKeySync(k);k = new KeyEvent(KeyEvent.ACTION_UP,keycode);sendKeySync(k);}else if(opt.equals("wait")){int millsecond = Integer.valueOf(mArgs[1]);Thread.sleep(millsecond);}else if(opt.equals("keypress")){int keycode = Integer.valueOf(mArgs[1]);int millsecond = Integer.valueOf(mArgs[2]);KeyEvent k = new KeyEvent(KeyEvent.ACTION_DOWN,keycode);sendKeySync(k);Thread.sleep(millsecond);k = new KeyEvent(KeyEvent.ACTION_UP,keycode);sendKeySync(k); }else if(opt.equals("touchpress")){float x = Float.valueOf(mArgs[1]);float y = Float.valueOf(mArgs[2]);int millsecond = Integer.valueOf(mArgs[3]);MotionEvent e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0);sendPointerSync(e);Thread.sleep(millsecond);e = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0);sendPointerSync(e);}else System.err.println("** Error: Unknown option: " + opt);}catch (RuntimeException ex){}Thread.sleep(2000);}private static void sendPointerSync(MotionEvent event) {try {(IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectPointerEvent(event, true);} catch (RemoteException e) {}}private static void sendKeySync(KeyEvent event) {try {(IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectKeyEvent(event, true);} catch (RemoteException e) {}}
}步骤三:编写Android.mk文件 LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := analog_control
LOCAL_MODULE_TAGS := optional
include $(BUILD_JAVA_LIBRARY)步骤四:编译模块并将生成jar报拷贝到设备的/system/framework/下启动终端,在Android源码根目录下运行:【. build/envsetup.sh】运行后可使用mm/mmm等命令进行模块编译,再进入步骤一创建的目录analog_control中,使用【mm】进行模块编译,编译后在/out/target/product/generic/system/framework下生成对应的analog_control.jar包。将生成的jar包拷贝到设备的/system/framework/下步骤五:编写可执行Shell文件传建analog_control文本文件,里边编写如下可执行Shell语句,使得上层应用可以通过执行Shell命令来实现模拟按键。base=/system
export CLASSPATH=$base/framework/analog_control.jar
exec app_process $base/bin AnalogControl $*将analog_control文件拷贝到设备的/system/bin/目录下,并修改为可执行权限【chmod 777 analog_control】 完成以上步骤便可在终端中通过命令来模拟消息,Android程序中通过在代码中运行命令行可以执行相应操作,前提需要su权限。String cmd = "执行命令";try {Process proc = Runtime.getRuntime().exec("su");  // 设备需要拥有su权限
proc.getOutputStream().write(cmd.getBytes());
proc.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}PS:各种触发时间命令如下: 1.touch事件 analog_control touch x y 2.move事件 analog_control move x1 y1 x2 y2 3.key事件 analog_control key 【按键消息代号】 (见上文所提到的 常见按键消息) 4.keypress事件 analog_control keypress 【按键消息代号】 【长按时间】 5.touchpress事件 analog_control touchpress x y 【长按时间】 三、编码实现 本节添加的源码很少,主要是实现模拟触摸按键,其余代码见上一讲,本节代码添加如下: 1.ServerThread.java /*** 此线程不断接收客户端发过来的请求信息*/
public void run()
{try{String content = null;//采用循环不断从Socket中读取客户端发送过来的数据while ((content = readFromClient()) != null){if(content.length() < 2) continue; // 避免发送空指令 或错误指令导致异常
String requestStr = content.substring(0, 2);Log.v("", "SocketServer ---> content : " + content + " , requestStr : " + requestStr );if(requestStr.equals(OPERATION_VOLUME)){MainActivity.systemManager.CtrlVolume(content);}else if(requestStr.equals(OPERATION_BRIGHTNESS)){// 需要在UI线程中实现 handler
                SystemManager.CtrlBrightness(MainActivity.mActivity,content);}// 下边所有操作都是通过模拟按键实现else if(requestStr.equals(OPERATION_CLICK)){String cmd = "analog_control key 23\n";SystemManager.execute(cmd);}else if(requestStr.equals(OPERATION_MENU)){String cmd = "analog_control key 82\n";SystemManager.execute(cmd);}else if(requestStr.equals(OPERATION_BACK)){String cmd = "analog_control key 4\n";SystemManager.execute(cmd);}else if(requestStr.equals(OPERATION_POWER)){String cmd = "analog_control key 26\n";SystemManager.execute(cmd);}else if(requestStr.equals(OPERATION_HOME)){String cmd = "analog_control key 3\n";SystemManager.execute(cmd);}else if(requestStr.equals(OPERATION_DIRECTION_TOP)){String cmd = "analog_control key 19\n";SystemManager.execute(cmd);}else if(requestStr.equals(OPERATION_DIRECTION_BOTTOM)){String cmd = "analog_control key 20\n";SystemManager.execute(cmd);}else if(requestStr.equals(OPERATION_DIRECTION_LEFT)){String cmd = "analog_control key 21\n";SystemManager.execute(cmd);}else if(requestStr.equals(OPERATION_DIRECTION_RIGHT)){String cmd = "analog_control key 22\n";SystemManager.execute(cmd);}}}catch (Exception e){e.printStackTrace();}
}2.SystemManager.java /*** 执行命令* @param cmd* @return*/public static boolean execute(String cmd){boolean isSuccess = false;try {Process proc = Runtime.getRuntime().exec("su");  // 设备需要拥有su权限
            proc.getOutputStream().write(cmd.getBytes());proc.getOutputStream().flush();isSuccess = true;} catch (IOException e) {e.printStackTrace();isSuccess = false;}Log.v("", "---> cmd : " + cmd + "  , isSuccess : " + isSuccess);return isSuccess;}四、后记&下篇内容 后记:第二小节通过命令行的方式模拟按键相关操作有个不足之处是每次命令都要延时1秒左右,如果要模拟鼠标就不行了,同事在AnalogControl.java中通过创建ServerSocket指定一个固定的端口号,然后客户端通过IP地址和指定端口号来控制模拟的方式不会延迟,而且不需要执行命令。由于时间关系本例不再涉及。 下篇主要内容是介绍基于Socket发送文件数据。 

转载于:https://www.cnblogs.com/MMLoveMeMM/articles/4104640.html

Android基于Socket无线遥控 - 模拟触摸按键篇framework jar相关推荐

  1. Android 基于Socket的聊天室

    原文地址为: Android 基于Socket的聊天室 Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路, ...

  2. 修改Android模拟器中System目录的内容(framework.jar)

    在做Android开发的时候,经常需要修改framework或是系统package里面的东西,如果没有硬件去的话,可以在模拟器上面去验证. 具体方法是,复制你所建立的模拟器版本的system.img到 ...

  3. Android Socket连接(模拟心跳包,断线重连,发送数据等)

    首页 博客 学院 下载 GitChat TinyMind 论坛 问答 商城 VIP 活动 招聘 ITeye CSTO 写博客 发Chat 喻志强的博客 耐心 细心 用心 传播正能量 RSS订阅 原 A ...

  4. 基于单片机智能灯光光控照明系统设计、基于单片机HX711电子秤自动计价系统设计、基于单片机GPRS远程测控系统设计、基于单片机多功能循迹避障无线遥控蓝牙智能小车-设计资料

    基于单片机智能灯光光控照明系统设计 智能光控照明系统设计原理: 本系统采用STC89C52系列的单片机为核心,利用BH1750传感器测量实时光照强度,并将亮度的模拟信号转化成数字信号,大大减少了系统的 ...

  5. 基于单片机HX711电子秤自动计价系统设计-基于单片机GPRS远程测控系统设计-818基于单片机循迹避障无线遥控蓝牙智能小车-基于单片机24s倒计时篮球积分器系统-基于单片机智能洗衣机控制系统

    816基于单片机HX711电子秤自动计价系统设计 本设计使用高精度电阻应变式压力传感器,用A/D转换器HX711(HX711数据手册)对传感器信号进行调理转换.AT89s52(AT89s52数据手册) ...

  6. 单片机遥控车c语言程序,基于51单片机的无线遥控小车设计[附发射接收程序]

    /***************************************************************/ /*[基于51单片机的无线遥控小车设计] 作者王*茹 */ /*** ...

  7. 基于51单片机的无线遥控门铃仿真程序原理图设计

    硬件设计 (末尾附文件) 原理图: 包含了发射和接收部分 仿真图:发射部分用按键模拟 程序设计 // //51单片机无线遥控门铃程序 // #include<REG51.H> #defin ...

  8. 基于单片机智能窗帘无线遥控控制设计(毕业设计)

    本设计是基于STC89C51单片机的遥控窗帘.采用按键和无线遥控两种控制方式,其中SC2262/SC2272 编码解码芯片组成无线发送接收模块:通过控制直流电机的正反转来控制窗帘的开关,并且可以指示运 ...

  9. 基于51单片机的无线遥控小车

    基于51单片机的无线遥控小车 材料:STC89C51(1个).nrf2401(2个).L298N(2个).小车底盘.18650(4个).按键若干.蜂鸣器 功能:前进.后退.左转.右转.鸣笛. 程序请移 ...

最新文章

  1. K单体型重建算法的研究
  2. pytorch cycleGAN代码学习1
  3. 漫话:如何给女朋友解释什么是缓存穿透、缓存击穿、缓存雪崩?
  4. PinkLotar 外挂汉化版+Mod 工具
  5. 计算机操作系统(八)---虚拟存储器
  6. flash的运算比较符
  7. RMS 相关下载链接
  8. EntityFramework Core 5.0 VS SQLBulkCopy
  9. close_wait过多服务器无响应,记一次大量CLOSE_WAIT连接导致的服务宕机
  10. spring集成testng
  11. mac idea 快捷键
  12. 802.11ac协议白皮书阅读笔记
  13. CMS是什么?如何识别CMS?
  14. MT7621原厂openwrt SDK使能串口2和串口3
  15. 【Python】笨方法学Python学习笔记1
  16. 安卓控件 - 列表视图
  17. 获取对话框当前cfont_获取对话框当前cfont_MFC设置对话框、字体对话框、颜色对话框(转)...
  18. 集合竞价如何买入_如何在集合竞价买卖股票
  19. 细胞系鉴定和表征测试-市场现状及未来发展趋势
  20. 永硕E盘:很实用的网络硬盘和网址收藏夹

热门文章

  1. 句句真研—每日长难句打卡Day20
  2. JavaScript学习(六十)—JSON
  3. 用JS实现简单的省市联动
  4. 94女,大厂程序员,收入50w+
  5. 退休前后,工资差距有多大?
  6. 如果有1千万以后不再有收入,没有任何理财方式,够花一辈子吗?
  7. 孩子学习缺乏主动性,应该怎么做?
  8. 方舟编译器需要安装吗,还是系统升级后自带的?
  9. 事业编和公务员哪个好?
  10. 玩抖音,你喜欢的,都是对自身没好处的