热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android提高之手游转电视游戏的模拟操控

这篇文章主要介绍了Android手游转电视游戏的模拟操控方法,是非常具有实用价值的功能,需要的朋友可以参考下

目前智能电视终端(智能电视和智能电视盒子)已经越来越火,过去主打视频功能,如今的智能电视终端不仅会继续完善视频功能,还会加入电视游戏功能,同时这也赶上了“电视游戏机解禁”的时机。

当今的大部分Android手游都能够在Android系统的电视终端上运行,其中有少数手游是原生支持手柄(例如MOGA手柄),这部分游戏可以作为电视游戏。但其他手游(射击,赛车,动作等游戏)若要在电视上玩,就需要修改操控模式,把触摸屏操控改为手柄实体键操控。

本文主要讲解的是如何使用/system/bin/之下的Input命令模拟按键和触摸屏操作,调用Input命令需要具备root权限。本文完整代码点击此处本站下载。

程序运行结果如下图所示:

 

本文核心RootCommand.java的代码如下,不建议把代码浓缩成全局静态方法,这里保持process和os这2个变量的生命周期直到app结束,可以减去多次初始化/释放的耗时。具体代码如下:

package com.hellogv.slinput;
import java.io.DataOutputStream;
import java.io.IOException;
import android.util.Log;
/**
 * 调用su执行input命令
 * 全局只调用一次init()和exit(),多次调用run()。
 * @author hellogv
 *
 */
public class RootCommand {
 private String TAG="RootCommand";
 private Process process = null;
 private DataOutputStream os = null;
 public void init() {
 try {
  process = Runtime.getRuntime().exec("su");
  os = new DataOutputStream(process.getOutputStream());
 } catch (IOException e) {
  Log.e(TAG, getExceptionMessage(e));
 }
 }
 /**
 * 模仿shell来执行命令,必须先root再使用
 * 
 * @param command
 * @return
 */
 public boolean run(String command) {
 try {
  os.writeBytes(command + "\n");
  os.flush();
 } catch (Exception e) {
  Log.e(TAG, getExceptionMessage(e));
  return false;
 }
 return true;
 }
 /**
 * 模仿shell来执行命令,必须先root再使用
 * 
 * @param command
 * @return
 */
 public void release() {
 try {
  os.writeBytes("exit\n");
  os.flush();
  process.waitFor();
 } catch (Exception e) {
  Log.e(TAG, getExceptionMessage(e));
 } finally {
  try {
  if (os != null) {
   os.close();
  }
  process.destroy();
  } catch (Exception e) {
  }
 }
 }
 private static String getExceptionMessage(Exception ex){
 String result="";
 StackTraceElement[] stes = ex.getStackTrace();
 for(int i=0;i

调用RootCommand的代码如下,input命令的使用格式详见代码:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rootCommand.init();
//模拟按下Home键
btnTestKey = (Button) this.findViewById(R.id.btnTestKey);
btnTestKey.setOnClickListener(new OnClickListener(){

 @Override
 public void onClick(View v) {
 //命令格式:input keyevent keycode
 rootCommand.run("/system/bin/input keyevent "+KeyEvent.KEYCODE_HOME);
 }
});
//模拟滑动触摸屏
btnTestSwipe= (Button) this.findViewById(R.id.btnTestSwipe);
btnTestSwipe.setOnClickListener(new OnClickListener(){
 @Override
 public void onClick(View v) {
 int x2 = MainActivity.this.getWindow().getDecorView().getWidth() - 10;
 //先去到桌面
 rootCommand.run("/system/bin/input keyevent "+KeyEvent.KEYCODE_HOME);
 //滑动桌面,命令格式:input swipe x1 y1 x2 y2
 for(int i=0;i<4;i++){
  rootCommand.run("/system/bin/input swipe 10 300 "+x2+" 400");
  rootCommand.run("/system/bin/input swipe "+x2+" 300 10 400");
 }
 }
});
//模拟点击触摸屏
btnTestTap= (Button) this.findViewById(R.id.btnTestTap);
btnTestTap.setOnClickListener( new OnClickListener(){
 @Override
 public void onClick(View v) {
  int[] location = new int[2];
  btnTestSwipe.getLocationOnScreen(location);
  int x = location[0]+btnTestSwipe.getWidth()/2;
  int y = location[1]+btnTestSwipe.getHeight()/2;
 //模拟点击btnTestTap
  rootCommand.run("/system/bin/input tap "+x+" "+y);
 }
});
//退出程序
btnExit = (Button) this.findViewById(R.id.btnExit);
btnExit.setOnClickListener( new OnClickListener(){
 @Override
 public void onClick(View v) {
 rootCommand.release();
 MainActivity.this.finish();
 }
});
//判断是否root过,没root过不可用
if(RootTools.isRootAvailable()==false){
 Toast.makeText(this, "本程序需要使用ROOT权限。", Toast.LENGTH_SHORT).show();
 this.finish();
}
}

感兴趣的朋友可以下载本实例的完整代码加以调试运行,相信会对大家的Android程序设计有很大的帮助。


推荐阅读
  • 本文针对初学者在创建Android项目时遇到的R.java文件错误提供了解决方案,通过实际案例和详细的日志分析,帮助读者快速定位并解决问题。 ... [详细]
  • 本文介绍了如何使用Java代码在Android设备上检测特定应用程序是否已安装。通过创建一个Intent并利用PackageManager查询该Intent的可用性来实现这一功能。 ... [详细]
  • 传送门A-Registration#include#definelllonglongusingnamespacestd;chars[15],t[15]; ... [详细]
  • 本题要求计算给定两个正整数a和b时,2的-a次方与2的-b次方之和,并将结果以最简分数形式表示。输入包括多组测试数据,每组数据包含两个在2到20范围内的整数。 ... [详细]
  • Android Studio 中 Gradle 使用的常见问题与解决方案
    本文探讨了在使用 Android Studio 进行开发时,遇到的与 Gradle 相关的问题,包括每次打开项目都需要下载 Gradle 和 Gradle 插件依赖包下载失败或卡顿等问题,并提供了详细的解决方法。 ... [详细]
  • 在本问题中,游戏的每一步状态均可以视为原始序列的一个子序列。通过定义一个动态规划函数 d(i, j),表示在最优策略下,先手玩家从原序列的第 i 个元素到第 j 个元素之间所能获得的最大分数。 ... [详细]
  • 深入理解动态链接库及其应用
    本文将探讨动态链接库的基本概念,包括Windows下的动态链接库(DLL)和Linux下的共享库(Shared Library),并详细介绍如何在Linux环境中创建和使用这些库。 ... [详细]
  • 请看|间隔时间_Postgresql 主从复制 ... [详细]
  • 本文详细介绍了如何在Python3环境中配置Appium1.4.6,并指导如何连接模拟器进行自动化测试。通过本文,您将了解从环境搭建到模拟器连接的完整流程。 ... [详细]
  • CentOS 7.2 配置防火墙端口开放
    本文介绍如何在 CentOS 7.2 系统上配置防火墙以开放特定的服务端口,包括 FTP 服务的临时与永久开放方法,以及如何验证配置是否生效。 ... [详细]
  • 本文介绍了如何利用Java中的URLConnection类来实现基本的网络爬虫功能,包括向目标网站发送请求、接收HTML响应、解析HTML以提取所需信息,并处理可能存在的递归爬取需求。 ... [详细]
  • 优化Input Checkbox与Label文本对齐的方法
    本文探讨了在网页设计中,如何有效解决input checkbox与label文字不对齐的问题。通过具体的代码实例和解决方案,帮助开发者实现更加美观的用户界面。 ... [详细]
  • 在使用高德地图内置导航功能时遇到AMapNavi组件出现空指针异常,经过多次排查发现问题是由于so库的兼容性引起的。本文将详细介绍如何通过调整项目配置来解决这一问题。 ... [详细]
  • 深入解析IGMP各版本特性及其演进
    本文详细探讨了Internet组管理协议(IGMP)的不同版本,包括IGMPv1的基础功能、IGMPv2的增强特性和IGMPv3的重要改进。特别分析了IGMPv3如何支持特定源组播(SSM)模型,并介绍了各版本之间的主要差异。 ... [详细]
  • 初探SoloPi:一款强大的Android自动化测试工具
    SoloPi是一款由支付宝开发的无线化、非侵入式且无需Root的Android自动化测试工具。它提供了录制回放、性能测试和一机多控三大核心功能,极大地提高了测试开发人员的工作效率。 ... [详细]
author-avatar
Kermit68_629
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有