Communication between Android device(phone) and PC via USB coding

依然范特西╮ 提交于 2019-12-08 07:31:01

问题


I searched for some websites and learned that the way to communicate between android device(phone) and PC via USB is to have an app implementing serversocket on the phone and another app implementing client socket on PC. I kinda fixed the phone side's app(no exception now), but I got an exception "Ljava.lang.StackTraceElement" trying to initiate a socket("localhost", 38300). Does anybody know what's going on with this and how I can fix it? I attached both side's of the code below.

My step to get it to run is as follows

: environment:

Samsung Android phone, Linux PC, Android Studio developer run on Linux

: connection step

  1. open android studio
  2. install one app on phone
  3. install another app on pc android emulator
  4. launch phone side app and click on button to attempt to wait for connection at this step, adb devices will have two devices
  5. adb -s emulator-5554 -s 1234567890(my phone) forward tcp:38300 tcp:38300
  6. launch pc side android emulator app and click on the button to initiate client socket

NOTE: as you all can see that I can use android studio "Android Monitor" window to see both phone's and PC's app shell's log.

phone side

    package com.example.seanhsu.androiddevice_serversocket;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.SocketTimeoutException;
    import java.util.Scanner;

    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Handler;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.TextView;
    import android.widget.Toast;

    public class AndroidDevice_ServerSocket extends AppCompatActivity implements OnClickListener{

    public static final String TAG = "Connection";
    public static final int TIMEOUT = 10;
    Intent i = null;
    TextView tv = null;
    private String connectionStatus = null;
    private String socketData = null;
    private Handler mHandler = null;
    ServerSocket server = null;

    String msg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_android_device__server_socket);

    // Set up click listeners for the buttons
    View connectButton = findViewById(R.id.connect_button);
    connectButton.setOnClickListener(this);
    View onBtn = findViewById(R.id.hdmi_on);
    onBtn.setOnClickListener(this);
    View offBtn = findViewById(R.id.hdmi_off);
    offBtn.setOnClickListener(this);

    // i = new Intent(this, Connected.class);
    mHandler = new Handler();
    }

    public void onClick(View v) {
    switch (v.getId()) {
        case R.id.connect_button:
            tv = (TextView) findViewById(R.id.connection_text);
            // initialize server socket in a new separate thread
            new Thread(initializeConnection).start();
            msg = "Attempting to connect...";
            Log.e(TAG, "1 "+msg);
            Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
            break;
        case R.id.hdmi_on:
            Log.e(TAG, "disconnect" + Globals.socketOut);
            if (Globals.socketOut != null) {
                Globals.socketOut.println("hdmiOn");
                Globals.socketOut.flush();
                msg = "disconnect hdmi on";
                Log.e(TAG, "2 "+msg);
                Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
            }
            else
            {
                msg = "disconnect hdmi on is null";
                Log.e(TAG, "3 "+msg);
                Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
            }
            break;
        case R.id.hdmi_off:
            Log.e(TAG, "disconnect" + Globals.socketOut);
            if (Globals.socketOut != null) {
                Globals.socketOut.println("hdmiOff!!");
                Globals.socketOut.flush();
                msg = "disconnect hdmi off";
                Log.e(TAG, "4 "+msg);
                Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
            }
            else
            {
                msg = "disconnect hdmi off is null";
                Log.e(TAG, "5 "+msg);
                Toast.makeText(this, msg, Toast.LENGTH_SHORT/*msg.length()*/).show();
            }
            break;
        }
    }

    private Runnable initializeConnection = new Thread() {
    public void run() {

        Socket client = null;
        // initialize server socket
        try {
            server = new ServerSocket(38300);
            server.setSoTimeout(TIMEOUT * 5000);

            // attempt to accept a connection
            client = server.accept();
            Globals.socketIn = new Scanner(client.getInputStream());
            Globals.socketOut = new PrintWriter(client.getOutputStream(),
                    true);

            // Globals.socketIn.
        } catch (SocketTimeoutException e) {
            // print out TIMEOUT
            Log.e(TAG, "aaa=== " + e);
            msg = "Connection has timed out! Please try again";
            Log.e(TAG, "6 "+msg);
            //Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();//method error, this causes program terminated
            mHandler.post(showConnectionStatus);
        } catch (IOException e) {
            Log.e(TAG, "bbb=== " + e);
            msg = "IO Exception";
            Log.e(TAG, "7 "+msg);
            //Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();//method error, this causes program terminated
        } finally {
            // close the server socket
            try {
                if (server != null)
                    server.close();
            } catch (IOException ec) {
                Log.e(TAG, "ccc=== " + ec);
                Log.e(TAG, "Cannot close server socket" + ec);
                msg = "Cannot close server socket";
                Log.e(TAG, "8 "+msg);
                //Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();//method error, this causes program terminated
            }
        }

        if (client != null) {
            Globals.connected = true;
            // print out success
            connectionStatus = "Connection was succesful!";
            Log.e(TAG, "9 "+connectionStatus);
            mHandler.post(showConnectionStatus);
            while (Globals.socketIn.hasNext()) {
                socketData = Globals.socketIn.next();
                mHandler.post(socketStatus);

            }
            // startActivity(i);
        }
    }
};
    /**
    * Pops up a "toast" to indicate the connection status
    */
    private Runnable showConnectionStatus = new Runnable() {
    public void run() {
        Log.e(TAG, "10 "+connectionStatus);
        Toast.makeText(getBaseContext(), connectionStatus,
                Toast.LENGTH_SHORT).show();
    }
    };

    private Runnable socketStatus = new Runnable() {

    public void run() {
        TextView tv = (TextView) findViewById(R.id.connection_text);
        tv.setText(socketData);
    }
    };

    public static class Globals {
    public static boolean connected;
    public static Scanner socketIn;
    public static PrintWriter socketOut;
    }
    }

PC side

    package com.example.seanhsu.pchost_clientsocket_withactivity;
    import android.support.v7.app.AppCompatActivity;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.SocketTimeoutException;
    import java.net.UnknownHostException;
    import java.util.Scanner;
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Handler;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.TextView;
    import android.widget.Toast;

    public class PCHost_ClientSocket_with_Activity extends AppCompatActivity implements OnClickListener{

    Socket socket;
    PrintWriter out;
    Scanner sc;
    String msg;

    private String TAG = "PCHost_ClientSocket_withActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_pchost__client_socket_with_);
    View connectButton = findViewById(R.id.connect_button);
    connectButton.setOnClickListener(this);

    //when the emulator start running, it's already in the emulator shell, so it cann't execute adb command
    //execAdb();
    }
    public void onClick(View v) {
    //cannot run on main thread
    //need to run on another thread, otherwise it will get android.os.NetworkOnMainThreadException exception
    new Thread(initializeConnection).start();
    //initializeConnection();

    /*while(sc.hasNext()) {
        System.out.println(System.currentTimeMillis() + " / " + sc.nextLine());
        Log.e(TAG, "12 "+System.currentTimeMillis() + " / " + sc.nextLine());
    }*/
    }
    //cannot run on main thread
    //need to run on another thread, otherwise it will get android.os.NetworkOnMainThreadException exception
    private Runnable initializeConnection = new Thread() {
    public void run() {
        msg = "initializeConnection";
        Log.e(TAG, msg);

        //Create socket connection
        try{
            Log.e(TAG, "============0============");
            socket = new Socket("localhost", 38300);
            Log.e(TAG, "============1============");
            out = new PrintWriter(socket.getOutputStream(), true);
            Log.e(TAG, "============2============");
            //in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            sc=new Scanner(socket.getInputStream());
            Log.e(TAG, "============3============");
            // add a shutdown hook to close the socket if system crashes or exists unexpectedly
            Thread closeSocketOnShutdown = new Thread() {
                public void run() {
                    try {
                        Log.e(TAG, "============4============");
                        socket.close();
                        msg = "closeSocketOnShutdown socket close";
                        Log.e(TAG, msg);
                        Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
                    } catch (IOException e) {
                        Log.e(TAG, "============5============");
                        e.printStackTrace();
                        msg = "closeSocketOnShutdown IOException";
                        Log.e(TAG, msg);
                        Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
                    }
                }
            };
            Log.e(TAG, "============6============");
            Runtime.getRuntime().addShutdownHook(closeSocketOnShutdown);
            Log.e(TAG, "============7============");
        } catch (UnknownHostException e) {
            //Print.fatalError(“Socket connection problem (Unknown host)”+e.getStackTrace());
            msg = "Socket connection problem (Unknown host)"+e.getStackTrace();
            Log.e(TAG, msg);
            Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            //Print.fatalError(“Could not initialize I/O on socket “+e.getStackTrace());
            msg = "Could not initialize I/O on socket "+e.getStackTrace();
            Log.e(TAG, msg);
            Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
        }
    }
};
}

I keep getting exception:

Could not initialize I/O on socket [Ljava.lang.StackTraceElement;@14710f5

Originally I also has IO exception on phone side app, but I add <uses-permission android:name="android.permission.INTERNET"/> in the manifest, it's OK now. Therefore, I also add <uses-permission android:name="android.permission.INTERNET"/> in PC side app's manifest, but still can't fix this problem.

来源:https://stackoverflow.com/questions/34036056/communication-between-android-devicephone-and-pc-via-usb-coding

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!