Android提高之手游轉(zhuǎn)電視游戲的模擬操控
目前智能電視終端(智能電視和智能電視盒子)已經(jīng)越來越火,過去主打視頻功能,如今的智能電視終端不僅會(huì)繼續(xù)完善視頻功能,還會(huì)加入電視游戲功能,同時(shí)這也趕上了“電視游戲機(jī)解禁”的時(shí)機(jī)。
當(dāng)今的大部分Android手游都能夠在Android系統(tǒng)的電視終端上運(yùn)行,其中有少數(shù)手游是原生支持手柄(例如MOGA手柄),這部分游戲可以作為電視游戲。但其他手游(射擊,賽車,動(dòng)作等游戲)若要在電視上玩,就需要修改操控模式,把觸摸屏操控改為手柄實(shí)體鍵操控。
本文主要講解的是如何使用/system/bin/之下的Input命令模擬按鍵和觸摸屏操作,調(diào)用Input命令需要具備root權(quán)限。本文完整代碼點(diǎn)擊此處本站下載。
程序運(yùn)行結(jié)果如下圖所示:
本文核心RootCommand.java的代碼如下,不建議把代碼濃縮成全局靜態(tài)方法,這里保持process和os這2個(gè)變量的生命周期直到app結(jié)束,可以減去多次初始化/釋放的耗時(shí)。具體代碼如下:
package com.hellogv.slinput;
import java.io.DataOutputStream;
import java.io.IOException;
import android.util.Log;
/**
* 調(diào)用su執(zhí)行input命令
* 全局只調(diào)用一次init()和exit(),多次調(diào)用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來執(zhí)行命令,必須先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來執(zhí)行命令,必須先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;
}
}
調(diào)用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);
}
});
//模擬滑動(dòng)觸摸屏
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);
//滑動(dòng)桌面,命令格式: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");
}
}
});
//模擬點(diǎn)擊觸摸屏
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;
//模擬點(diǎn)擊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權(quán)限。", Toast.LENGTH_SHORT).show();
this.finish();
}
}
感興趣的朋友可以下載本實(shí)例的完整代碼加以調(diào)試運(yùn)行,相信會(huì)對(duì)大家的Android程序設(shè)計(jì)有很大的幫助。
- Android實(shí)現(xiàn)完整游戲循環(huán)的方法
- Unity3D游戲引擎實(shí)現(xiàn)在Android中打開WebView的實(shí)例
- Android游戲開發(fā)實(shí)踐之人物移動(dòng)地圖的平滑滾動(dòng)處理
- Android 游戲開發(fā)之Canvas畫布的介紹及方法
- android游戲載入的activity跳轉(zhuǎn)到游戲主菜單的activity具體實(shí)現(xiàn)
- 解析Android游戲中獲取電話狀態(tài)進(jìn)行游戲暫停或繼續(xù)的解決方法
- Android 游戲引擎libgdx 資源加載進(jìn)度百分比顯示案例分析
- Android Handler之消息循環(huán)的深入解析
- Android基本游戲循環(huán)實(shí)例分析
相關(guān)文章
剖析Android Activity側(cè)滑返回的實(shí)現(xiàn)原理
在很多的App中,都會(huì)發(fā)現(xiàn)利用手指滑動(dòng)事件,進(jìn)行高效且人性化的交互非常有必要,那么它是怎么實(shí)現(xiàn)的呢,本文給大家解析實(shí)現(xiàn)原理,對(duì)Activity側(cè)滑返回實(shí)現(xiàn)代碼感興趣的朋友一起看看吧2021-06-06
Android解決ScrollView下嵌套ListView和GridView中內(nèi)容顯示不全的問題
今天小編就為大家分享一篇關(guān)于Android解決ScrollView下嵌套ListView和GridView中內(nèi)容顯示不全的問題,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
Android?O對(duì)后臺(tái)Service限制詳解
這篇文章主要為大家介紹了Android?O對(duì)后臺(tái)Service限制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
Android實(shí)現(xiàn)讀取掃碼槍內(nèi)容(條形碼)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)讀取掃碼槍內(nèi)容、條形碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Android回調(diào)與觀察者模式的實(shí)現(xiàn)原理
這篇文章主要為大家詳細(xì)介紹了Android回調(diào)與觀察者模式的實(shí)現(xiàn)原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
Android 運(yùn)用@JvmName解決函數(shù)簽名沖突問題詳解
JvmName注解是Kotlin提供的一個(gè)可以變更編譯器輸出的注解,這里簡(jiǎn)單的介紹一下其使用規(guī)則,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-07-07
Android實(shí)現(xiàn)自定義View控件的流程詳解
這篇文章主要為大家詳細(xì)介紹了Android中實(shí)現(xiàn)自定義View控件的流程,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下2023-06-06
Android實(shí)現(xiàn)短信加密功能(發(fā)送加密短信、解密本地短信)
這篇文章主要介紹了android實(shí)現(xiàn)短信加密功能的相關(guān)資料,功能包括發(fā)送加密短信、解密本地短信,感興趣的小伙伴們可以參考一下2016-01-01
Android Gradle多渠道打包的實(shí)現(xiàn)方法
這篇文章主要介紹了Android Gradle多渠道打包的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

