android socket wifi 连接PC实现简单的PPT控制器(源码)
以上是手机端简单的运行效果图
通过本文只是想来简单介绍一下关于android socket编程。
向上服务器端代码:
package nate.PPT.control; 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; public class PPTServer { private final static int RIGHT = 1; private final static int LEFT = 2; private final static int SHIFTF5 = 0; private final static int ESC = 3; private static int key; //注意这里用的输入输出流的对象 private static ObjectInputStream fromClient; private static ObjectOutputStream fromServer; public static void main(String[] args) throws IOException, ClassNotFoundException, AWTException, InterruptedException{ ServerSocket sSocket = new ServerSocket(2011); System.out.println("waiting a connection from the client"); Robot robot = new Robot(); Socket sock = sSocket.accept(); System.out.println("recv a connection"); fromClient = new ObjectInputStream(sock.getInputStream()); fromServer = new ObjectOutputStream(sock.getOutputStream()); do{ Choices choice = (Choices)fromClient.readObject(); System.out.println("the flag is " + choice.getKey()); key = choice.getKey(); switch(key){ case SHIFTF5: robot.keyPress(KeyEvent.VK_SHIFT); Thread.sleep(20); robot.keyPress(KeyEvent.VK_F5); Thread.sleep(10); robot.keyRelease(KeyEvent.VK_F5); robot.keyRelease(KeyEvent.VK_SHIFT); Thread.sleep(10); break; case LEFT: robot.keyPress(KeyEvent.VK_LEFT); Thread.sleep(10); robot.keyRelease(KeyEvent.VK_LEFT); Thread.sleep(10); break; case RIGHT: robot.keyPress(KeyEvent.VK_RIGHT); Thread.sleep(10); robot.keyRelease(KeyEvent.VK_RIGHT); Thread.sleep(10); break; case ESC: robot.keyPress(KeyEvent.VK_ESCAPE); Thread.sleep(10); robot.keyPress(KeyEvent.VK_ESCAPE); Thread.sleep(10); break; default: break; } }while(key != -1); System.out.println("exit the app"); fromClient.close(); fromServer.close(); sock.close(); sSocket.close(); } }本例中,注意一下所用的输入输出流对象,关于这个java中已经很清楚了,就不多说。同时,本例中使用java中的Robot来模拟按键,即PPT中的快捷键从而实现控制PPT的目的。当然,大家都知道,使用ObjectInputStream、ObjectOutputStream传输对象首先还需下面的条件。即传送的对象所属的类,该类必须实现Serializable接口!同时注意在android手机客户端,我们需要同样拥有这样一个类型!!!将此类copy过去即可,这些都是java中的知识。
package nate.PPT.control; import java.io.Serializable; public class Choices implements Serializable{ private int key; public Choices(int key) { super(); this.key = key; } public int getKey() { return key; } public void setKey(int key) { this.key = key; } }
上面类包含了传输的信息数据内容。
来看看client端的代码,部署在android手机端:
package nate.PPT.control; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.widget.Button; public class PPTClient extends Activity { private Button start; private Button escape; private Button forward; private Button back; private Socket sock; private ObjectOutputStream fromClient; private ObjectInputStream fromServer; private final static int RIGHT = 1; private final static int LEFT = 2; private final static int SHIFTF5 = 0; private final static int ESC = 3; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { //sock = new Socket(InetAddress.getByName("125.71.69.199"),2011); sock = new Socket(InetAddress.getByName("125.70.223.165"),2011); fromClient = new ObjectOutputStream(sock.getOutputStream()); fromServer = new ObjectInputStream(sock.getInputStream()); } catch (UnknownHostException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } start = (Button)this.findViewById(R.id.start); escape = (Button)this.findViewById(R.id.escape); forward = (Button)this.findViewById(R.id.froward); back = (Button)this.findViewById(R.id.back); start.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View v) { Choices choice = new Choices(SHIFTF5); try { fromClient.writeObject(choice); System.out.println("send the start shift + f5"); } catch (IOException e) { e.printStackTrace(); } } }); escape.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View arg0) { Choices choice = new Choices(ESC); try { fromClient.writeObject(choice); System.out.println("send the escape"); } catch (IOException e) { e.printStackTrace(); } } }); forward.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View v) { Choices choice = new Choices(RIGHT); try { fromClient.writeObject(choice); System.out.println("send the right (the next)"); } catch (IOException e) { e.printStackTrace(); } } }); back.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View v) { Choices choice = new Choices(LEFT); try { fromClient.writeObject(choice); System.out.println("send the left (the last)"); } catch (IOException e) { e.printStackTrace(); } } }); } /** * 监听BACK键 * @param keyCode * @param event * @return */ public boolean onKeyDown(int keyCode, KeyEvent event) { if ( event.getKeyCode() == KeyEvent.KEYCODE_BACK){ AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("exit app"); builder.setMessage("You will exit the app..."); //builder.setIcon(R.drawable.stat_sys_warning); builder.setPositiveButton("OK",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startMain); System.exit(0); } }); builder.setNegativeButton("Cancel",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.show(); } return super.onKeyDown(keyCode, event); } }
代码还是很简单的,这里不多说了,强调一下的是,client端除了一个activity的类外,还有上面的Choices类!!!与服务器端的类型一模一样!同时,别忘记了需要在android manifest.XML文件中添加
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/>
用户权限!!!别忘记添加。。。
当然,代码还有很多需要改进的地方,比如要解决按下可能延迟PPT没有反应,但是又不知道是否真的按下等问题,我们可以在手机端的按钮上加上一个震动的效果,这样我们就能准确的知道我们是否按下手机上的按键。这个应该不难吧!不过本篇文章主要还是简单介绍android socket编程与PC的连接。
如果有朋友需要整个工程源码的,在下面留下邮箱,我将发送给你!
由于大家需要的网友比较多,我已经将资源放在此处,http://download.csdn.net/detail/natepan/3849822,大家可以去自由下载,谢谢。