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

本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!

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

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

     本文主要讲解的是如何使用/system/bin/之下的Input命令模拟按键和触摸屏操作,调用Input命令需要具备root权限。本文代码可以到http://download.csdn.net/detail/hellogv/6927571下载,程序运行结果如下:

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

 

本文核心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<stes.length;i++){
			result=result+stes[i].getClassName() 
			+ "." + stes[i].getMethodName() 
			+ "  " + stes[i].getLineNumber() +"line"
			+"\r\n";
		}
		return result;
	}
}
调用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平台下实现录音及播放录音功能的简介


下一篇:Android编译系统环境初始化过程分析