Android 手机遥控器控制机顶盒(电视)

您所在的位置:网站首页 电视盒子怎么连接手机遥控器 Android 手机遥控器控制机顶盒(电视)

Android 手机遥控器控制机顶盒(电视)

2024-07-13 18:11| 来源: 网络整理| 查看: 265

公司需求: 参考悟空遥控器做下手机控制机顶盒的功能,手机端apk界面参考遥控器,机顶盒apk在设置里面加个开关,打开的时候运行个后台server,手机端发送数据机顶盒的server接收到后处理相关动作。

需求出来了怎么实现呢?首先应用程序的通信无非就是Socket与Http,其中Socket又可以用TCP和UDP,HTTP的话就衍生出很多方式,基础的HTTP GET和POST请求,然后就是WebService的SOAP。

在这些方式中,Socket当然是最基础的。因此先从Socket开始。 首先是服务器端:打开服务器,等待客户端链接并接收消息即KeyCode,响应相应事件; 然后是客户端:模拟遥控器的UI界面,搭好界面,为每个控件添加点击事件并赋值相应KeyCode,连接服务器,将KeyCode信息传递给服务器端。 完成之后需要在资源配置文件中添加网络权限:

所有完成之后,测试时发现响应按键时只能在当前应用内使用,当离开此应用界面时,会报无权限异常,这时需要在Manifest.xml中添加 最高权限:

android:sharedUserId="android.uid.system"

这时需要在SDK下使用mk文件编译: Android.mk

ifneq ($(BOARD_USE_DEFAULT_APPINSTALL),false) LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := RemoteTV LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) endif

整个思路就是这样,下面上代码:

ClientActivity,这里用到了StrictMode(严苛模式),不懂的可以百度了解了解,在这里我只做了数字键和上下左右键的模拟,有需要的可以自己添加:

public class ClientActivity extends Activity implements OnClickListener { private EditText mServerIp; private EditText mServerPort; private EventSender mEventSender; @Override protected void onCreate(Bundle savedInstanceState) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .penaltyLog() .penaltyDeath() .build()); super.onCreate(savedInstanceState); setContentView(R.layout.activity_client); mServerIp = (EditText) findViewById(R.id.cli_adr_edi); mServerPort = (EditText) findViewById(R.id.cli_port_edi); findViewById(R.id.cli_connect_btn).setOnClickListener(this); findViewById(R.id.num_1).setOnClickListener(this); findViewById(R.id.num_2).setOnClickListener(this); findViewById(R.id.num_3).setOnClickListener(this); findViewById(R.id.num_4).setOnClickListener(this); findViewById(R.id.num_5).setOnClickListener(this); findViewById(R.id.num_6).setOnClickListener(this); findViewById(R.id.num_7).setOnClickListener(this); findViewById(R.id.num_8).setOnClickListener(this); findViewById(R.id.num_9).setOnClickListener(this); findViewById(R.id.btn_up).setOnClickListener(this); findViewById(R.id.btn_left).setOnClickListener(this); findViewById(R.id.btn_right).setOnClickListener(this); findViewById(R.id.btn_down).setOnClickListener(this); } @Override public void onClick(View v) { int code = -1; switch (v.getId()) { case R.id.cli_connect_btn: if(mEventSender != null) mEventSender.close(); mEventSender = new EventSender(mServerIp.getText().toString(), Integer.valueOf(mServerPort.getText().toString())); mEventSender.connect(); return; case R.id.num_1: code = KeyEvent.KEYCODE_1; break; case R.id.num_2: code = KeyEvent.KEYCODE_2; break; case R.id.num_3: code = KeyEvent.KEYCODE_3; break; case R.id.num_4: code = KeyEvent.KEYCODE_4; break; case R.id.num_5: code = KeyEvent.KEYCODE_5; break; case R.id.num_6: code = KeyEvent.KEYCODE_6; break; case R.id.num_7: code = KeyEvent.KEYCODE_7; break; case R.id.num_8: code = KeyEvent.KEYCODE_8; break; case R.id.num_9: code = KeyEvent.KEYCODE_9; break; case R.id.btn_up: code=KeyEvent.KEYCODE_DPAD_UP; break; case R.id.btn_left: code=KeyEvent.KEYCODE_DPAD_LEFT; break; case R.id.btn_down: code=KeyEvent.KEYCODE_DPAD_DOWN; break; case R.id.btn_right: code=KeyEvent.KEYCODE_DPAD_RIGHT; break; } if(mEventSender == null) return; mEventSender.println(createKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, code))); } private String createKeyEvent(KeyEvent event) { JSONObject json = new JSONObject(); try { json.put("Event", event.getKeyCode()); } catch (JSONException e) { e.printStackTrace(); } return json.toString(); } public class EventSender { private static final String TAG = "EventSender"; private Socket mSocket; private String mDstAddress; private int mDstPort; private PrintWriter mPrintWriter; private EventSender(String dstAddress, int dstPort){ Log.d(TAG, "EventSender"); mDstAddress = dstAddress; mDstPort = dstPort; mSocket = new Socket(); } public void println(String str){ mPrintWriter.println(str); } public boolean close(){ Log.d(TAG, "close()"); if(mSocket != null){ try { mSocket.close(); mSocket = null; return true; } catch (IOException e) { e.printStackTrace(); } } return false; } public boolean connect(){ Log.d(TAG, "connect()"); try { if (mSocket != null && !mSocket.isConnected()) { Log.d(TAG, "new InetSocketAddress()"); mSocket.connect(new InetSocketAddress(mDstAddress, mDstPort)); mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true); mSocket.setKeepAlive(true); } return true; }catch (IOException e) { e.printStackTrace(); } return false; } } }

服务器端:

public class ServerActivity extends Activity implements OnClickListener{ private static final String TAG = "ServerActivity"; private RemoteServer mRemoteServer; private EditText mServerPort; private TextView mServerRecEvent; private int keycode; private Instrumentation instrumentation; @Override protected void onCreate(Bundle savedInstanceState) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .penaltyLog() .penaltyDeath() .build()); super.onCreate(savedInstanceState); setContentView(R.layout.activity_server); findViewById(R.id.ser_port_btn).setOnClickListener(this); mServerPort = (EditText) findViewById(R.id.ser_port_edi); mServerRecEvent = (TextView) findViewById(R.id.ser_recev_event); } @Override public void onClick(View v) { openServer(Integer.valueOf(mServerPort.getText().toString())); } public void openServer(int dstPort){ Log.d(TAG, "openServer() - dstPort:" + dstPort); mServerRecEvent.setText(""); if (mRemoteServer == null) { mRemoteServer = new RemoteServer(dstPort); if(mRemoteServer.openServer()) { mServerRecEvent.setText("服务启动成功!!!!/r/n"); } Log.d(TAG, "openServer() - mRemoteServer:" + mRemoteServer); } } private void onEvent(String line) { Log.d(TAG, "line: " + line); try { JSONObject object=new JSONObject(line); keycode = (int) object.get("Event"); Log.d(TAG, "keycode: " + keycode); if (instrumentation==null){ instrumentation=new Instrumentation(); } //通过KeyCode响应相应操作 instrumentation.sendKeyDownUpSync(keycode); Log.d(TAG, "event key : " + keycode); } catch (JSONException e) { e.printStackTrace(); } Message msg = Message.obtain(); msg.what = 0; msg.obj = line; mHandler.sendMessage(msg); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { String text = mServerRecEvent.getText().toString(); mServerRecEvent.setText(text + String.valueOf(msg.obj)); } }; class RemoteServer implements Runnable{ private static final String TAG = "RemoteServer"; private int mPort; private ServerSocket mServerSocket; private boolean mIsClose = false; public boolean isClose(){ return mIsClose; } public boolean close(){ try { mServerSocket.close(); mServerSocket = null; mIsClose = true; } catch (IOException e) { e.printStackTrace(); } return mIsClose; } public RemoteServer(int port){ Log.d(TAG, "RemoteServer()"); mPort = port; } public boolean openServer(){ try { mServerSocket = new ServerSocket(mPort); new Thread(this).start(); return true; } catch (IOException e) { e.printStackTrace(); } return false; } public void run() { try { while (!mIsClose) { Socket socket = mServerSocket.accept(); new ServerThread(socket); } } catch (IOException e) { } } private class ServerThread extends Thread { private Socket client; private BufferedReader in; public ServerThread(Socket s) throws IOException { client = s; in = new BufferedReader(new InputStreamReader(client.getInputStream())); start(); } public void run() { android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY); try { String line = in.readLine(); while (!mIsClose) { if(line != null){ onEvent(line); } line = in.readLine(); } Log.d(TAG, "--- See you, bye! ---"); client.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

MainActivity

public class MainActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn_client).setOnClickListener(this); findViewById(R.id.btn_server).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_client: startActivity(new Intent(this, ClientActivity.class)); break; case R.id.btn_server: startActivity(new Intent(this, ServerActivity.class)); break; } } }

布局就不放了,有需要的可以看下实现过程,主要就是Socket通信,下面上界面,界面时测试界面,很丑,凑合着看吧: 首先在客户端和盒子上安装编译好的APP,在盒子端进入服务器端,输入端口号:img-w10 在手机端进入客户端,输入服务器端的IP地址和端口号: img-w150 注意这里,连接成功时没有做判断,点击连接服务后,如果没反应即连接成功了。 还有:盒子和手机一定要在同一个局域网下!!!客户端输入的端口号和服务器输入的端口号一定要一致。

代码下载地址:http://download.csdn.net/download/json_jerry/9955125 本来想0积分提供,不知道为什么最低需要1积分。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3