套接字代码在Android Marshmallow工作正常但在Android Nougat中出错

时间:2017-03-24 05:06:06

标签: android sockets

我正在尝试开发一个用于播放演示文稿的android远程控制代码。该项目分为两部分:

  1. 套接字服务器 我们需要启动服务器并等待客户端连接。当客户端发送命令时,服务器使用Robot.KeyPress处理命令
  2. 移动应用程序(套接字客户端) 这是一个移动应用程序,它向服务器发送一些命令,如“F5”。
  3. 当前的代码在Android手机中工作正常,Marshmallow更新(在Lollipop和Marshmallow上试过)但是当在Nougat上尝试相同的代码时,应用程序崩溃了(Android Remote已经停止,再次打开应用程序)。

    套接字服务器代码:

        import java.awt.AWTException;
        import java.awt.Robot;
        import java.awt.event.InputEvent;
        import java.awt.event.KeyEvent;
        import java.awt.MouseInfo;
        import java.awt.Point;
        import java.io.BufferedReader;
        import java.io.IOException;
        import java.io.InputStream;
        import java.io.InputStreamReader;
        import java.io.OutputStream;
        import java.io.PrintWriter;
        import java.net.InetSocketAddress;
        import java.net.ServerSocket;
        import java.net.Socket;
    
        public class RemoteDroidServer {
    
        private static ServerSocket server = null;
        private static Socket client = null;
        private static BufferedReader in = null;
        private static String line;
        private static boolean isConnected=true;
        private static Robot robot;
        private static final int SERVER_PORT = 8998;
    
        public static void main(String[] args) {
            boolean leftpressed=false;
            boolean rightpressed=false;
    
            try{
                robot = new Robot();
                server = new ServerSocket(SERVER_PORT); //Create a server socket on port 8998
                client = server.accept(); //Listens for a connection to be made to this socket and accepts it
                in = new BufferedReader(new InputStreamReader(client.getInputStream())); //the input stream where data will come from client
                System.out.println("Connected to server");
            }catch (IOException e) {
                System.out.println("Error in opening Socket");
                System.exit(-1);
            }catch (AWTException e) {
                System.out.println("Error in creating robot instance");
                System.exit(-1);
            }
    
            //read input from client while it is connected
            while(isConnected){
                try{
                line = in.readLine(); //read input from client
                System.out.println(line); //print whatever we get from client
                //-----------------VLC Commands--------------------------------
                /*
                Space Bar to Play or Pause. ...
                F to toggle Full Screen. ...
                A to Change Aspect ratio. ...
                Z to Change Zoom Mode. ...
                Ctrl+RightArrow to move forward
                Ctrl+LeftArrow to move backward
                Alt+Left/Alt+Right to Fast Forward slow. ... 
                */
    
                //if user clicks on fullscreen  (Key- F)
                if(line.equalsIgnoreCase("fullscreen")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_F);
                    robot.keyRelease(KeyEvent.VK_F);
                }
    
                //if user click on Change Aspect ratio (Key- A)
                if(line.equalsIgnoreCase("aspectratio")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_A);
                    robot.keyRelease(KeyEvent.VK_A);
                }
    
                //if user clicks on Increase Volume (CTRL + UpArrowKey)
                if(line.equalsIgnoreCase("volplus")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_CONTROL);
                    robot.keyPress(KeyEvent.VK_UP);
                    // CTRL+UpArrowKey is now pressed (receiving application should see a "key down" event.)
                    robot.keyRelease(KeyEvent.VK_UP);
                    robot.keyRelease(KeyEvent.VK_CONTROL);
                }
    
                //if user clicks on Decrease Volume (CTRL + DownArrowKey)
                if(line.equalsIgnoreCase("volminus")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_CONTROL);
                    robot.keyPress(KeyEvent.VK_DOWN);
                    // CTRL+DownArrowKey is now pressed (receiving application should see a "key down" event.)
                    robot.keyRelease(KeyEvent.VK_DOWN);
                    robot.keyRelease(KeyEvent.VK_CONTROL);
                }
    
                //if user clicks on move forward (CTRL + RightArrow)
                if(line.equalsIgnoreCase("forward")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_CONTROL);
                    robot.keyPress(KeyEvent.VK_RIGHT);
                    // CTRL+UpArrowKey is now pressed (receiving application should see a "key down" event.)
                    robot.keyRelease(KeyEvent.VK_RIGHT);
                    robot.keyRelease(KeyEvent.VK_CONTROL);
                }
                //if user clicks on move forward (CTRL + LeftArrow)
                if(line.equalsIgnoreCase("backward")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_CONTROL);
                    robot.keyPress(KeyEvent.VK_LEFT);
                    // CTRL+UpArrowKey is now pressed (receiving application should see a "key down" event.)
                    robot.keyRelease(KeyEvent.VK_RIGHT);
                    robot.keyRelease(KeyEvent.VK_LEFT);
                }
    
                //-------------------------------------------------------------
                //if user clicks on f5
                if(line.equalsIgnoreCase("F5")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_F5);
                    robot.keyRelease(KeyEvent.VK_F5);
                }
    
                //if user clicks on esc
                if(line.equalsIgnoreCase("escape")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_ESCAPE);
                    robot.keyRelease(KeyEvent.VK_ESCAPE);
                }
    
                //if user clicks on first slide
                if(line.equalsIgnoreCase("home")){
                    //Simulate press and release of key 'Home'
                    robot.keyPress(KeyEvent.VK_HOME);
                    robot.keyRelease(KeyEvent.VK_HOME);
                }
    
                //if user clicks on last slide
                if(line.equalsIgnoreCase("end")){
                    //Simulate press and release of key 'END'
                    robot.keyPress(KeyEvent.VK_END);
                    robot.keyRelease(KeyEvent.VK_END);
                }
                //----------------------------------------------------------------------------          
                //if user clicks on next
                if(line.equalsIgnoreCase("next")){
                    //Simulate press and release of key 'n'
                    robot.keyPress(KeyEvent.VK_N);
                    robot.keyRelease(KeyEvent.VK_N);
                }
    
                //if user clicks on previous
                else if(line.equalsIgnoreCase("previous")){
                    //Simulate press and release of key 'p'
                    robot.keyPress(KeyEvent.VK_P);
                    robot.keyRelease(KeyEvent.VK_P);                    
                }
                //if user clicks on play/pause
                else if(line.equalsIgnoreCase("play")){
                    //Simulate press and release of spacebar
                    robot.keyPress(KeyEvent.VK_SPACE);
                    robot.keyRelease(KeyEvent.VK_SPACE);
                }
                //input will come in x,y format if user moves mouse on mousepad
                else if(line.contains(",")){
                    float movex=Float.parseFloat(line.split(",")[0]);//extract movement in x direction
                    float movey=Float.parseFloat(line.split(",")[1]);//extract movement in y direction
                    Point point = MouseInfo.getPointerInfo().getLocation(); //Get current mouse position
                    float nowx=point.x;
                    float nowy=point.y;
                    robot.mouseMove((int)(nowx+movex),(int)(nowy+movey));//Move mouse pointer to new location
                }
                //if user taps on mousepad to simulate a left click
                else if(line.contains("left_click")){
                    //Simulate press and release of mouse button 1(makes sure correct button is pressed based on user's dexterity)
                    robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
                    robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
                }
                //Exit if user ends the connection
                else if(line.equalsIgnoreCase("exit")){
                    isConnected=false;
                    //Close server and client socket
                    server.close();
                    client.close();
                }
                } catch (IOException e) {
                    System.out.println("Read failed");
                    System.exit(-1);
                }
            }
        }
    }
    

    我的Android代码是:

    import android.content.Context;
    import android.content.DialogInterface;
    import android.os.AsyncTask;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.Socket;
    
    public class Powerpoint extends AppCompatActivity implements View.OnClickListener{
    
        Context context;
        Button esc;
        Button nextButton;
        Button previousButton;
        Button end;
        Button btnConnect;
        Button f5;
        Button home;
    
        private boolean isConnected=false;
        private boolean mouseMoved=false;
        private Socket socket;
        private PrintWriter out;
        private String serverIP= Constants.SERVER_IP;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_powerpoint);
    
            context = this; //save the context to show Toast messages
    
            //Get references of all buttons
            esc = (Button)findViewById(R.id.btnEnd);
            nextButton = (Button)findViewById(R.id.btnNext);
            previousButton = (Button)findViewById(R.id.btnPrevious);
            f5 = (Button)findViewById(R.id.btnStart);
            btnConnect = (Button)findViewById(R.id.btnConnect);
            home = (Button)findViewById(R.id.btnHome);
            end = (Button)findViewById(R.id.btnLastSlide);
    
            //this activity extends View.OnClickListener, set this as onClickListener
            //for all buttons
            esc.setOnClickListener(this);
            nextButton.setOnClickListener(this);
            previousButton.setOnClickListener(this);
            f5.setOnClickListener(this);
            home.setOnClickListener(this);
            end.setOnClickListener(this);
    
            btnConnect.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // get prompts.xml view
                    LayoutInflater li = LayoutInflater.from(context);
                    View promptsView = li.inflate(R.layout.prompt, null);
    
                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                            context);
    
                    // set prompts.xml to alertdialog builder
                    alertDialogBuilder.setView(promptsView);
    
                    final EditText userInput = (EditText) promptsView
                            .findViewById(R.id.editTextDialogUserInput);
    
                    // set dialog message
                            alertDialogBuilder
                    .setCancelable(false)
                            .setPositiveButton("OK",
                                    new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog,int id) {
                                            // get user input and set it to result
                                            // edit text
                                            serverIP=userInput.getText().toString();
                                            Toast.makeText(getApplicationContext(),"Ip:"+serverIP,Toast.LENGTH_SHORT).show();
                                            ConnectPhoneTask connectPhoneTask = new ConnectPhoneTask();
                                            connectPhoneTask.execute(serverIP); //try to connect to server in another thread
    
                                        }
                                    })
                            .setNegativeButton("Cancel",
                                    new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog,int id) {
                                            dialog.cancel();
                                        }
                                    });
    
                    // create alert dialog
                    AlertDialog alertDialog = alertDialogBuilder.create();
    
                    // show it
                    alertDialog.show();
    
    
                }
            });
    
        }
    
        //OnClick method is called when any of the buttons are pressed
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btnEnd:
                    if (isConnected && out!=null) {
                        out.println(Constants.ESCAPE);//send "escape" to server
                    }
    
                    break;
                case R.id.btnNext:
                    if (isConnected && out!=null) {
                        out.println(Constants.NEXT); //send "next" to server
                    }
                    break;
                case R.id.btnPrevious:
                    if (isConnected && out!=null) {
                        out.println(Constants.PREVIOUS); //send "previous" to server
                    }
                    break;
    
                case R.id.btnStart:
                    if (isConnected && out!=null) {
                        out.println(Constants.F5); //send "previous" to server
                    }
                    break;
                case R.id.btnHome:
                    if (isConnected && out!=null) {
                        out.println(Constants.HOME); //send "home" to server
                    }
                    break;
                 case R.id.btnLastSlide:
                    if (isConnected && out!=null) {
                        out.println(Constants.END); //send "end" to server
                    }
                    break;
            }
    
        }
    
        @Override
        public void onDestroy()
        {
            super.onDestroy();
            if(isConnected && out!=null) {
                try {
                    out.println("exit"); //tell server to exit
                    socket.close(); //close socket
                } catch (IOException e) {
                    Log.e("remotedroid", "Error in closing socket", e);
                }
            }
        }
    
        public class ConnectPhoneTask extends AsyncTask<String,Void,Boolean> {
    
            @Override
            protected Boolean doInBackground(String... params) {
                boolean result = true;
                try {
                    InetAddress serverAddr = InetAddress.getByName(params[0]);
                    socket = new Socket(serverAddr, Constants.SERVER_PORT);//Open socket on server IP and port
                    isConnected=true;
                } catch (IOException e) {
                    Log.e("remotedroid", "Error while connecting", e);
                    result = false;
                    isConnected=false;
                }
                return result;
            }
    
            @Override
            protected void onPostExecute(Boolean result)
            {
                isConnected = result;
                Toast.makeText(context, isConnected ? "Connected to server!" : "Error while connecting", Toast.LENGTH_LONG).show();
                try {
                    if(isConnected) {
                        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                                .getOutputStream())), true); //create output stream to send data to server
                    }
                }catch (IOException e){
                    Log.e("remotedroid", "Error while creating OutWriter", e);
                    Toast.makeText(context,"Error while connecting",Toast.LENGTH_LONG).show();
                }
            }
        }
    
    }
    

    常量类代码:

    public class Constants {
        public static final String SERVER_IP = "192.168.1.5";
        public static final int SERVER_PORT = 8998;
        public static final String NEXT="next";
        public static final String PREVIOUS="previous";
        public static final String ESCAPE="escape";
        public static final String F5="f5";
        public static final String HOME="home";
        public static final String END="end";
    
        public static final String SPACE="play";
        public static final String VOLUP="volplus";
        public static final String VOLDOWN="volminus";
        public static final String FASTFORWARD="forward";
        public static final String BACKWARD="backward";
        public static final String ZOOM="fullscreen";
        public static final String ASPECTRATIO="aspectratio";
    }
    

    布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_powerpoint"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.sahajsolns.socketprogrammingdemo.Powerpoint">
    
    
        <Button
            android:text="Start PPT"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginTop="48dp"
            android:id="@+id/btnStart"
            android:layout_below="@+id/lblModuleTitle"
            android:layout_centerHorizontal="true" />
    
        <TextView
            android:text="Powerpoint Module"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="45dp"
            android:id="@+id/lblModuleTitle"
            android:textSize="18sp"
            android:textColor="@android:color/holo_orange_dark"
            android:textStyle="normal|bold"
            android:lineSpacingExtra="8sp" />
    
        <Button
            android:text="Next Slide"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/btnNext"
            android:layout_below="@+id/btnStart"
            android:layout_toRightOf="@+id/btnStart"
            android:layout_toEndOf="@+id/btnStart" />
    
        <Button
            android:text="End PPT"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/btnEnd"
            android:layout_below="@+id/btnNext"
            android:layout_toRightOf="@+id/btnPrevious"
            android:layout_toEndOf="@+id/btnPrevious" />
    
        <Button
            android:text="Previous Slide"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/btnPrevious"
            android:layout_below="@+id/btnStart"
            android:layout_toLeftOf="@+id/btnStart"
            android:layout_toStartOf="@+id/btnStart" />
    
        <Button
            android:text="Connect To Server"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:id="@+id/btnConnect" />
    
        <Button
            android:text="Home"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_below="@+id/btnPrevious"
            android:layout_toLeftOf="@+id/btnEnd"
            android:layout_toStartOf="@+id/btnEnd"
            android:id="@+id/btnHome" />
    
        <Button
            android:text="Last Slide"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/btnLastSlide"
            android:layout_below="@+id/btnNext"
            android:layout_toRightOf="@+id/btnEnd"
            android:layout_toEndOf="@+id/btnEnd" />
    
    </RelativeLayout>
    

0 个答案:

没有答案