Android开发之远距离PC控制

这篇文章的目的是为大家提供一个Android端控制PC端软件的目的,如控制电脑上的PPT、音乐播放器等软件。在这里我为大家介绍下基本的流程,并在最后附上我自己调试并实现的代码,不足之处请批评指正。

首先,Android遥控PC端,主要的框架是基于客户端/服务器模式,基本上就是android作为客户端,然后PC上运行服务器,两者之间通过Socket连接进行服务器与客户端的数据传输响应,最后由服务端调用相关方法操作PC软件。大致流程如下:

这里需要注意的就是socket连接的时候不要放在主线程中,不然会报错,(android4.0以上),所以我这里使用的是AsyncTask来实现异步操作。第二个注意的地方是连接自己主机的时候还是在命令行里查看下自己的IP地址吧,ipconfig,不要相信什么127.0.0.1或者10.0.2.2的,反正我试了都是不靠谱的,网上几年前的老帖子都是过时了的。

下面是具体代码:主要分为客户端和服务端的:

服务端代码:

package com.sjm.robot;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.DataInputStream;

public class PPTServer {
	//PPT播放热键
    private final static String RIGHT = "RightNext";
    private final static String LEFT = "LeftForword";
    private final static String SHIFTF5 = "ShiftF5";
    private final static String ESC = "ESC";

    //酷狗音乐播放
    private final static String KUGO_START = "AltF5";
	private final static String KUGO_NEXT ="AltLeft";
	private final static String KUGO_BACK = "AltRight";
	private final static String KUGO_PAUSE = "AltF5";
	private final static String KUGO_SLIENT = "AltS";
	private final static String KUGO_AUDIO_UP = "AltUp";
	private final static String KUGO_AUDIO_DOWN = "AltDown";
	private final static String KUGO_SHOW_WORDS = "CtrlAltD";

    private static int key;
    private static int num;
    // 注意这里用的输入输出流的对象
    private static DataInputStream fromClient;
    private static ServerSocket serversocket;
    private static Socket socket;
    public static void main(String[] args)  {
    	new ServerThread().start();

    }
    public static class ServerThread extends Thread{
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		super.run();
    		try {
				serversocket = new ServerSocket(9999);
				System.out.println("等待一个连接");
				while (true)
				{
					socket = serversocket.accept();//阻塞
					System.out.println("获取一个请求");
					//连接上之后先构建一个Robot对象
					try
					{
						Robot robot = new Robot();
						fromClient =new java.io.DataInputStream(socket.getInputStream());
						byte[] buffer = new byte[512];
						fromClient.read(buffer);
						String str = new String(buffer);
						if (str.contains(SHIFTF5))
						{
							System.out.println("请求操作:"+str);
							robot.keyPress(KeyEvent.VK_SHIFT);
							robot.keyPress(KeyEvent.VK_F5);
							robot.keyRelease(KeyEvent.VK_F5);
							robot.keyRelease(KeyEvent.VK_SHIFT);
						}
						else if (str.contains(RIGHT)) {
							System.out.println("请求操作:"+str);
							robot.keyPress(KeyEvent.VK_RIGHT);
							robot.keyRelease(KeyEvent.VK_RIGHT);
						}
						else if (str.contains(LEFT)) {
							System.out.println("请求操作:"+str);
							robot.keyPress(KeyEvent.VK_LEFT);
							robot.keyRelease(KeyEvent.VK_LEFT);
						}
						else if (str.contains(ESC)) {
							System.out.println("请求操作:"+str);
							robot.keyPress(KeyEvent.VK_ESCAPE);
							robot.keyRelease(KeyEvent.VK_ESCAPE);
						}
						/**
						 * 这里开始是酷狗的按键控制
						 */
						else if (str.contains(KUGO_START)) {
							System.out.println("请求操作:酷狗音乐开始播放");
							robot.keyPress(KeyEvent.VK_ALT);
							robot.keyPress(KeyEvent.VK_F5);
							robot.keyRelease(KeyEvent.VK_F5);
							robot.keyRelease(KeyEvent.VK_ALT);
						}
						else if (str.contains(KUGO_NEXT)) {
							System.out.println("请求操作:酷狗音乐开始播放");

							robot.keyPress(KeyEvent.VK_ALT);
							robot.keyPress(KeyEvent.VK_RIGHT);
							robot.keyRelease(KeyEvent.VK_RIGHT);
							robot.keyRelease(KeyEvent.VK_ALT);
						}
						else if (str.contains(KUGO_BACK)) {
							System.out.println("请求操作:酷狗音乐开始播放");
							robot.keyPress(KeyEvent.VK_ALT);
							robot.keyPress(KeyEvent.VK_LEFT);
							robot.keyRelease(KeyEvent.VK_LEFT);
							robot.keyRelease(KeyEvent.VK_ALT);
						}
						else if (str.contains(KUGO_SLIENT)) {
							System.out.println("请求操作:静音");
							robot.keyPress(KeyEvent.VK_ALT);
							robot.keyPress(KeyEvent.VK_S);
							robot.keyRelease(KeyEvent.VK_S);
							robot.keyRelease(KeyEvent.VK_ALT);
						}
						else if (str.contains(KUGO_AUDIO_UP)) {
							System.out.println("请求操作:增加音量");
							robot.keyPress(KeyEvent.VK_ALT);
							robot.keyPress(KeyEvent.VK_UP);
							robot.keyRelease(KeyEvent.VK_UP);
							robot.keyRelease(KeyEvent.VK_ALT);
						}
						else if (str.contains(KUGO_AUDIO_DOWN)) {
							System.out.println("请求操作:降低音量");
							robot.keyPress(KeyEvent.VK_ALT);
							robot.keyPress(KeyEvent.VK_DOWN);
							robot.keyRelease(KeyEvent.VK_DOWN);
							robot.keyRelease(KeyEvent.VK_ALT);
						}
						else if (str.contains(KUGO_SHOW_WORDS)) {
							robot.keyPress(KeyEvent.VK_CONTROL);
							robot.keyPress(KeyEvent.VK_ALT);
							robot.keyPress(KeyEvent.VK_D);
							robot.keyRelease(KeyEvent.VK_D);
							robot.keyRelease(KeyEvent.VK_ALT);
							robot.keyRelease(KeyEvent.VK_CONTROL);
						}
					} catch (AWTException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        	try {
    			serversocket.close();
    			socket.close();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
}

客户端代码:

package com.example.controlpptonpc;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class KuGoPlay extends Activity implements OnClickListener{
	private Button btn_start,btn_next,btn_back;
	private Button btn_slient,btn_audio_up,btn_audio_down;
	private static int flag = 0;
	private final static String START = "AltF5";
	private final static String NEXT ="AltLeft";
	private final static String BACK = "AltRight";
	private final static String PAUSE = "AltF5";
	private final static String SLIENT = "AltS";
	private final static String AUDIO_UP = "AltUp";
	private final static String AUDIO_DOWN = "AltDown";
	private final static String SHOW_WORDS = "CtrlAltD";

	//Java里字符串一样的话String被认为是一个变量
	private Socket clientsocket;
	private final static int port = 9999;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.kugo_play_layout);
		init();
		click_event();
	}

	/**
	 *
	 */
	public void init()
	{
		btn_start = (Button) findViewById(R.id.btn_start);
		btn_next = (Button) findViewById(R.id.btn_next);
		btn_back = (Button) findViewById(R.id.btn_back);
		btn_slient = (Button) findViewById(R.id.btn_slient);
		btn_audio_up = (Button) findViewById(R.id.btn_audio_up);
		btn_audio_up.getBackground().setAlpha(100);
		btn_audio_down = (Button) findViewById(R.id.btn_audio_down);
		btn_audio_down.getBackground().setAlpha(100);
	}

	public void click_event()
	{
		btn_start.setOnClickListener(this);
		btn_next.setOnClickListener(this);
		btn_back.setOnClickListener(this);
		btn_slient.setOnClickListener(this);
		btn_audio_up.setOnClickListener(this);
		btn_audio_down.setOnClickListener(this);
	}
	/**
	 *
	 * @param v
	 */
	@SuppressLint("NewApi")
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn_start:
			if ("播放".contains((btn_start.getText().toString().trim()))) {
				new Music_Play_AsyncTask().execute(START);
				btn_start.setText("暂停");
				btn_start.setBackground(getResources().getDrawable(R.drawable.music_pause));
			}
			else if ("暂停".contains((btn_start.getText().toString().trim()))) {
				new Music_Play_AsyncTask().execute(PAUSE);
				btn_start.setBackground(getResources().getDrawable(R.drawable.music_play1));
				btn_start.setText("播放");
			}
			break;
		case R.id.btn_next:
			new Music_Play_AsyncTask().execute(NEXT);
			break;
		case R.id.btn_back:
			new Music_Play_AsyncTask().execute(BACK);
			break;
		case R.id.btn_slient:
			if (0 == flag) {
				new Music_Play_AsyncTask().execute(SLIENT);
				btn_slient.setBackground(getResources().getDrawable(R.drawable.slient));
				flag = 1;
			}
			else if (1 == flag) {
				new Music_Play_AsyncTask().execute(SLIENT);
				btn_slient.setBackground(getResources().getDrawable(R.drawable.music_slient));
				flag = 0;
			}
			break;
		case R.id.btn_audio_up:
			new Music_Play_AsyncTask().execute(AUDIO_UP);
			break;
		case R.id.btn_audio_down:
			new Music_Play_AsyncTask().execute(AUDIO_DOWN);
			break;
		default:
			break;
		}
	}
	/**
	 *
	 * @author sjm
	 *
	 */
	private class Music_Play_AsyncTask extends AsyncTask<String, Void, String>
	{

		@Override
		protected void onPostExecute(String result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
		}

		@Override
		protected String doInBackground(String... params) {
			// TODO Auto-generated method stub
			String result = params[0];
			switch (result) {
			case START:
				try {
					clientsocket = new Socket("172.21.212.2", port);
					DataOutputStream out = new DataOutputStream(clientsocket.getOutputStream());
					String buffer = START;
					out.write(buffer.getBytes());
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (clientsocket == null) {
					result = "操作失败:"+result;
				}
				result = "开始播放KuGo";
				break;
			case NEXT:
				try {
					clientsocket = new Socket("172.21.212.2", port);
					DataOutputStream out = new DataOutputStream(clientsocket.getOutputStream());
					String buffer = NEXT;
					out.write(buffer.getBytes());
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (clientsocket == null) {
					result = "操作失败:"+result;
				}
				result = "下一首";
				break;

			case BACK:
				try {
					clientsocket = new Socket("172.21.212.2", port);
					DataOutputStream out = new DataOutputStream(clientsocket.getOutputStream());
					String buffer = BACK;
					out.write(buffer.getBytes());
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (clientsocket == null) {
					result = "操作失败:"+result;
				}
				result = "上一首";
				break;
			case SLIENT:
				try {
					clientsocket = new Socket("172.21.212.2", port);
					DataOutputStream out = new DataOutputStream(clientsocket.getOutputStream());
					String buffer = SLIENT;
					out.write(buffer.getBytes());
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				break;
			case AUDIO_UP:
				try {
					clientsocket = new Socket("172.21.212.2", port);
					DataOutputStream out = new DataOutputStream(clientsocket.getOutputStream());
					String buffer = AUDIO_UP;
					out.write(buffer.getBytes());
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (clientsocket == null) {
					result = "操作失败:"+result;
				}
				result = "音量增加";
				break;
			case AUDIO_DOWN:
				try {
					clientsocket = new Socket("172.21.212.2", port);
					DataOutputStream out = new DataOutputStream(clientsocket.getOutputStream());
					String buffer = AUDIO_DOWN;
					out.write(buffer.getBytes());
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (clientsocket == null) {
					result = "操作失败:"+result;
				}
				result = "音量降低";
				break;
			case SHOW_WORDS:
				try {
					clientsocket = new Socket("172.21.212.2", port);
					DataOutputStream out = new DataOutputStream(clientsocket.getOutputStream());
					String buffer = SHOW_WORDS;
					out.write(buffer.getBytes());
				} catch (UnknownHostException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				break;
			default:
				break;
			}
			return result;
		}
	}
}

需要声明的是服务端的代码包含了PPT的控制和音乐播放器的控制,而客户端的代码我只给了音乐播放器端的设置,PPT的雷同就不贴了,具体代码都有注释,大家就自己理解吧。程序测试有效,我已经在家舒服的远距离遥控了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-31 09:40:07

Android开发之远距离PC控制的相关文章

Android开发使用TotalControl调试遇到的问题(备注)

背景:Android开发,使用TotalControl控制手机进行调试. 过程:Eclipse调试一直正常,某天下午突然提示:无法启动ADB.exe,请确认是否在对应的路径下. 怀疑是自己程序写的有问题,于是把之前调试通过的程序翻出,一样无法运行. 当时郁闷,各种BAIDU,无法解决问题. 基本解决的方式是:关闭TotalControl的ADB.exe,进程,手动启动SDK下的ADB. 结果:SDK下的ADB无法启动.关闭TotalControl不能连接手机,无法调试. 不能确定原因,直接放大招

android开发-wifi连接eclipse开发调试环境

android开发请远离数据线! 方法很简单: 第一步,首先你需要在你的手机上安装一个终端模拟器工具,这里我推荐 androidterm_1,0,48.apk,搜下各大app store都会下载到. 第二步,在手机打开这个终端工具,输入命令: su//获取root权限 setprop service.adb.tcp.port 5555//设置监听的端口,端口可以自定义,如5554,5555是默认的 stop adbd//关闭adbd start adbd//重新启动adbd 第三步,记录下你手机

Android开发之控制手机音频

本实例通过MediaPlayer播放一首音乐并通过AudioManager控制手机音频,关于AudioManager的详解可参照:Android开发之AudioManager(音频管理器)详解 程序运行效果图: 实例代码: package com.jph.audiomanagerdemo; import android.media.AudioManager; import android.media.MediaPlayer; import android.os.Bundle; import an

Android开发学习---android下的数据持久化,保存数据到rom文件,android_data目录下文件访问的权限控制

一.需求 做一个类似QQ登录似的app,将数据写到ROM文件里,并对数据进行回显. 二.截图 登录界面: 文件浏览器,查看文件的保存路径:/data/data/com.amos.datasave/files/LoginTest.txt------/data/data/(包名)/files/(文件名) 导出的文件内容: 三.实现代码 新建一个Android 工程.这里我选择的是2.1即API 7,进行开发的,其它都是默认下一步下一步即可. /datasave/res/layout/activity

android开发开源宝贝——持续更新。。。

2016年11月11日更新 http://www.apkbus.com/forum-417-1.html http://p.codekk.com/detail/Android/hejunlin2013/LivePlayback www.codekk.com https://github.com/Trinea/android-open-project Android 开源项目分类汇总 我们的微信公众号:codekk.二维码如下: 专注于 Android 开源分享.源码解析.框架设计.Android

(转) Android开发性能优化简介

作者:贺小令 随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序.以上理由,足以需要开发人员更加专心去实现和优化你的代码了.选择合适的算法和数据结构永远是开发人员最先应该考虑的事情.同时,我们应该时刻牢记,写出高效代码的两条基本的原则:(1)不要做不必要的事:(2)不要分配不必要的内存. 我从去年开始接触Android开发,以下结合自己的一点项目经验,同时参考了Google的优

强烈鄙视那些:自己完全不用android手机,却在做android开发的人

前言: 最近参加android技术交流会,看到几个同时用mac和iphone的人,以为他们是全栈工程师(android和ios都会) , 谁知道交流下来,居然只是做android开发的,ios根本不会. 而且问他们平时用什么手机,回答都是:iphone. 还带着鄙视的语气说:android都是屌丝用的,不好用.心里顿时一万个草泥马:你tmd 既然这么鄙视 ,你为什么还做android开发,还靠android找工作. 为什么不去做ios开发??? 这种人,肯定水平不咋地. 只会装B 和 吹牛逼.因

Android开发必备的21个免费资源和工具

转载自: http://blog.csdn.net/shimiso/article/details/6788375 Android移动开发平台现在不是一个“火”字能形容的,今年Android平台在市场占有率上相比去年取得的886%增长!如果我只看增长率,iPhone据统计才有61%的增长.而创造了山寨概念的联发科也在近期宣布将进军Android.这些事实可以给你关于两个平台流行度的印像,但是事实上,这些数据告诉了智能机开发员的谁才是真正的赢家.在时下,智能机越来越流行,因此成为一个快速增长的An

Android开发中应该注意的事项

1.子线程中不能更新界面,更新界面必须在主线程中进行 2.Fragment注意的事项: a)  Activity调用Fragment中的方法 b)  Thread或者Handler调用Fragment中的方法 需要注意getActivity()可能为空:需要加入下面代码避免空指针 If(getActivity() == null || !isAdd()){ return; } 3.String类型的常量和变量相互比较要使用常量equals变量,因为变量可能为空: If(常量.equals(变量)