将数据从Android设备发送到tap top

时间:2017-11-03 08:41:09

标签: java android sockets bluetooth serial-port

我有一个在Android设备(手机/平板电脑)上运行的Android应用程序。 我想在设备和笔记本电脑附近创建一个连接,以便将一些数据从Android应用程序发送到笔记本电脑上运行的Java应用程序。

根据您的经验,实现该连接的最佳/最简单方法是什么? 我应该连接套接字吗?串口连接?蓝牙连接?也许无线? 我认为套接字连接是我对这个特定项目最不喜欢的。

我应该说我以前没有尝试过任何关于android的连接类型。

有什么建议吗?我愿意接受建议 谢谢。

2 个答案:

答案 0 :(得分:0)

您可以尝试通过Wifi使用套接字!我设法使它工作,这很容易:)

  1. 将您的笔记本电脑设为接入点
  2. 通过Android界面将您的Android连接到本地接入点网络
  3. 在笔记本电脑上启动C ++(或其他)套接字服务器(将设置端口号)
  4. 启动您的Android应用,在同一端口号上打开套接字并通过inputStreamBuffer读取数据
  5. 以下是打开套接字并读取数据的AsyncTask示例

    class WifiDataAsyncTask extends AsyncTask<Integer, Void, Void> {
    
        private final String TAG = this.getClass().getName();
        private Socket sock;
        private Context context;
        private WifiManager wifiManager;
        private BufferedReader br;
    
        WifiDataAsyncTask(Context context, WifiManager wifiManager) {
            this.context = context;
            this.wifiManager = wifiManager;
        }
    
        @Override
        protected Void doInBackground(Integer... numPort) {
            int rawChar;
            sock = new Socket();
            try {
    
                Log.d(TAG, "Creating socket on IP " + getIpAddress(wifiManager) + ":" + numPort[0]);
                sock.setReuseAddress(true);
            }
            catch (IOException e) {
                Log.d(TAG, "Error set reuseaddress");
                e.printStackTrace();
            }
            try {
                sock.connect(new InetSocketAddress(getIpAddress(wifiManager), numPort[0]));
            } catch (IOException ex) {
                Log.d(TAG, "Error connection socket");
                ex.printStackTrace();
            }
    
            if (sock.isConnected()) {
                try {
                    br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
    
                    StringBuilder toSave = new StringBuilder();
                    // -1 : end of the stream
                    // isCancelled() tells you if the asynctask has been cancelled in the Main Activity
                    while ((rawChar = br.read()) != -1 && !isCancelled()) {
                        char c = (char) rawChar;
                        if (c == '\0') {
                            // Add the char to the string to save
                            toSave.append('\n');
                            // DO STUFF WITH YOUR STRING DATA
                            toSave.setLength(0);
                        } else {
                            toSave.append(c);
                        }
                    }
                } catch (IOException ex) {
                    Log.d(TAG, "Error read InputStream:");
                    ex.printStackTrace();
                }
                try {
                    closeConnection();
                } catch (IOException e) {
                    Log.d(TAG, "Error close connection:");
                    e.printStackTrace();
                }
            }
            return null;
        }
    
        private void closeConnection() throws IOException {
            // If InputStream Closed (Wifi disconnected or server stopped)
            try {
                if (br != null) {
                    br.close();
                }
            } finally {
                sock.close();
                Log.d(TAG, "Socket closed");
                // Tell Main Activity that the socket has closed
                Intent intent = new Intent(context.getResources().getString(R.string.CloseSocketAction));
                context.sendBroadcast(intent);
            }
        }
    
        private String getIpAddress(WifiManager wifiManager) {
            DhcpInfo dhcpInfo = wifiManager.getDhcpInfo();
            byte[] ipAddress = convert2Bytes(dhcpInfo.serverAddress);
            try {
                return InetAddress.getByAddress(ipAddress).getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        private byte[] convert2Bytes(int hostAddress) {
            return new byte[]{(byte) (0xff & hostAddress),
                    (byte) (0xff & (hostAddress >> 8)),
                    (byte) (0xff & (hostAddress >> 16)),
                    (byte) (0xff & (hostAddress >> 24))};
        }
    }
    

    主要活动可以是这样的:

    public class TestFragment extends Fragment {
    
        private final String TAG = this.getClass().getName();
        private View mLayout;
        private WifiManager wifiManager;
        private WifiDataAsyncTask wifiDataAsyncTask;
        private CloseSocketReceiver closeSocketReceiver;
    
        class CloseSocketReceiver extends BroadcastReceiver {
    
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
    
                if (action.equals(getResources().getString(R.string.CloseSocketAction))) {
                    Log.d(TAG, "CloseSocketReceiver");
                }
            }
        }
    
        private void startWifiDataAsyncTask() {
            // Create AsyncTasks
            wifiDataAsyncTask = new WifiDataAsyncTask(getContext(), wifiManager);
            wifiDataAsyncTask.execute(getResources().getInteger(R.integer.NUMPORT));
        }
    
        private void stopWifiDataAsyncTask() {
            wifiDataAsyncTask.cancel(true);
        }
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    
            return inflater.inflate(R.layout.fragment_osselet, container, false);
        }
    
        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
    
            mLayout = view;
    
            wifiManager = (WifiManager) getActivity().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    
            // Create receiver
            closeSocketReceiver = new CloseSocketReceiver();
    
        }
    
        @Override
        public void onStart() {
            super.onStart();
            getActivity().registerReceiver(closeSocketReceiver, new IntentFilter(getResources().getString(R.string.CloseSocketAction)));
        }
    
        public void onStop() {
            super.onStop();
            getActivity().unregisterReceiver(closeSocketReceiver);
        }
    }
    

    在清单中,添加互联网权限以使用Wifi:

    <uses-permission android:name="android.permission.INTERNET" />
    

    这是发送String消息的C ++ Server.cpp:

    #include <errno.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include <strings.h>
    #include <string.h>
    #include "Server.h"
    #include "common.h"
    #include <unistd.h>
    #include <sys/ioctl.h>
    
    using namespace std;
    
    Server::Server(int num_port) {
        this->num_port = num_port;
    
    }
    
    void Server::init() {   // Init socket
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
        if(sockfd < 0){
            fprintf(stderr, "Error opening socket\n");
        }
    
        // Allow to reuse socket immediately after closing server
        int enabled = 1;
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enabled, sizeof(int)) < 0) {
            fprintf(stderr, "setsockopt(SO_REUSEADDR) failed\n");
        }
        printf("Server Socket created on port %d\n", num_port);
    
        // Init server_addr
        bzero((char*) &server_addr, sizeof(server_addr));
    
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = INADDR_ANY;
        server_addr.sin_port = htons(num_port);
    
        // Init newsockfd
        newsockfd = -1;
    
    
    }
    
    Server::~Server() {
        close(sockfd);
        close(newsockfd);
    }
    
    void Server::bind() {
        // Binding socket
        if(::bind(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0){
            fprintf(stderr, "Error Binding Socket\n");
            exit(1);
        }
    }
    
    void Server::listen(int maxClient) {
        printf("Look up for clients on port %d\n", num_port);
    
        // Define number of max clients
        ::listen(sockfd, maxClient);
    }
    
    int Server::start() {
    
        struct sockaddr_in cli_addr;
        socklen_t clilen = sizeof(cli_addr);
    
        fd_set set;
        struct timeval timeout;
        int rv;
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
    
        newsockfd = -1;
    
        // Check if newsockfd assigned or Ctrl-C handled
        while (newsockfd == -1 && signaled == 0) {
            // Reset into the loop
            // After listen returns, set have been updated and
            // starting another select will not wait on
            // the updated file descriptors
            // After first call, no client here, set updated and not 
            // listen anymore -> need to reset
            FD_ZERO(&set); /* Clear set */
            FD_SET(sockfd, &set); /* Add file descriptor to the set */
    
            rv = select(sockfd + 1, &set, NULL, NULL, &timeout);
            if (rv == -1) {
                fprintf(stderr, "Error select\n");
                exit(1);
            }
            else if (rv == 0) {
                //fprintf(stderr, "Timeout occurred\n");
            }
            else {
                // Accept client
                newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &clilen);
    
                if(newsockfd < 0){
                    fprintf(stderr, "Error Client not accepted by server\n"); 
                }
                // Set timeout to write
                struct timeval timeout;
                timeout.tv_sec = 0;
                timeout.tv_usec = 10;
    
                if (setsockopt (newsockfd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout)) < 0) {
                    fprintf(stderr, "setsockopt(SO_SNDTIMEO) failed\n");
                }   
                printf("Client accepted on port %d\n", num_port);
            }
        }
        printf("Server.start() terminated\n");
        return newsockfd;       
    }
    
    int Server::sendData(char* toSend, int size) {
        // Check is socket closed
        int n = write(newsockfd, toSend, size);
        if (n < 0) {
            fprintf(stderr, "Error sending message\n"); 
        }
        else {
            //printf("Message %s sent to the client on port %d\n", toSend, num_port);
        }
        return n;
    }   
    
    void Server::closeClientSocket() {
        close(newsockfd);
    }
    
    void Server::stop() {
        printf("Closing sockets\n");
        close(newsockfd);
        close(sockfd);
    }
    

    最后是Server.h

    #ifndef SERVER_H
    #define SERVER_H
    
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    class Server {
    
        private:
            int num_port;
            int sockfd, newsockfd;
            struct sockaddr_in server_addr;
    
        public:
            Server(int num_port); // Constructor
            ~Server(); // Desctructor
    
            void init();
            void allowReuse();
            void bind();
            void listen(int);
            int start();
            int sendData(char*, int);
            void closeClientSocket();
            void stop();
    };
    
    #endif
    

    希望它有所帮助!

答案 1 :(得分:0)

此示例使用RX

显示

<强> MainActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mStartRX = TrafficStats.getTotalRxBytes();
    mStartTX = TrafficStats.getTotalTxBytes();

    if (mStartRX == TrafficStats.UNSUPPORTED || mStartTX == TrafficStats.UNSUPPORTED) {
        AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle("Uh Oh!");
        alert.setMessage("Your device does not support traffic stat monitoring.");
        alert.show();
    } else {
        mHandler.postDelayed(mRunnable, 1000);
    }
}

我们需要更新我们的显示并重新安排runnable:

private final Runnable mRunnable = new Runnable() {
    public void run() {
        TextView RX = (TextView) findViewById(R.id.RX);
        TextView TX = (TextView) findViewById(R.id.TX);
        long rxBytes = TrafficStats.getTotalRxBytes() - mStartRX;
        RX.setText(Long.toString(rxBytes));
        long txBytes = TrafficStats.getTotalTxBytes() - mStartTX;
        TX.setText(Long.toString(txBytes));
        mHandler.postDelayed(mRunnable, 1000);
    }
};