C# 读取从PC接收到的安卓手机数据

C# 读取从PC接收到的安卓手机数据,c#,android,usb,nfc,C#,Android,Usb,Nfc,我需要实现一个解决方案,从通过USB电缆连接到PC的android设备读取数据。i、 e.连接到PC的手机将通过另一个android设备通过NFC接收数据,其中PC-C程序必须读取插入式android手机接收到的数据,如下所示 [PC]<----(2. read data) usb cable----[android phone]<-----NFC (1. transmit string)-----[android phone] [PC]我认为这是你应该做的。当收到来自NFC的数据

我需要实现一个解决方案,从通过USB电缆连接到PC的android设备读取数据。i、 e.连接到PC的手机将通过另一个android设备通过
NFC
接收数据,其中PC-
C
程序必须读取插入式android手机接收到的数据,如下所示

[PC]<----(2. read data) usb cable----[android phone]<-----NFC (1. transmit string)-----[android phone]

[PC]我认为这是你应该做的。当收到来自NFC的数据时,将其存储在SD卡中预定义的位置。同时,运行一个连续的线程来为该特定文件执行adb拉取。如果adb pull下载了文件,那么您就完成了

另一种方法是监视logcat输出:您的应用程序可以向logcat输出写入一条消息,该输出通过您的应用程序进行监视

上的示例代码和其他讨论

但@Sagar所提到的似乎也是合理的,如果做得好,可以防止任何数据丢失。使用logcat方法,如果断开连接,则断开连接期间传输的任何数据都将丢失

您可以只设置一个端口,然后在预定义端口上向目标PC的IP地址发出HTTP请求。您需要提前配置Android应用程序,将请求发送到特定的IP地址或扫描一系列IP地址以查找正确的IP地址(在这种情况下,您的侦听器需要响应“搜索”类型的请求)

实际上,您正在C#中创建一个小型REST服务。那你就可以了。

首先,我不是C#程序员,所以请原谅我从中复制粘贴C#socket客户端

基本上,如果您想通过USB与Android应用程序通信,您需要指示手机通过
adb
(Android调试桥)创建端口转发,然后您可以使用普通TCP/IP套接字与客户端建立流通信

因此,首先,您必须在PC上安装正确的驱动程序(您可以在制造商网站上找到它们),以便在运行
adb设备时正确识别您的手机:

C:\adt-bundle-windows-x86-20140321\sdk\platform-tools>adb devices
List of devices attached
039d78fa2518e606        device
接下来,您需要在Android端设置端口转发,以便将PC上本地主机的套接字连接正确转发到手机上的本地主机。这也可以通过亚洲开发银行进行:

C:\adt-bundle-windows-x86-20140321\sdk\platform-tools>adb forward tcp:6000 tcp:6000
验证它是否成功:

C:\adt-bundle-windows-x86-20140321\sdk\platform-tools>adb forward --list
039d78fa2518e606 tcp:6000 tcp:6000
现在,您可以在Android端创建一个常规套接字服务器应用程序。很抱歉,这个示例非常简单(我很晚才注意到这个问题,没有时间实现正确的通信协议)。但这应该向您展示如何在客户端和主机之间传输字符串,并且您可以实现必要的循环,或者在需要时实现更复杂的传输协议

基本上,这只是默认的Android项目,添加了一个类,在一个单独的线程中运行(GUI和网络活动不能在同一个线程中运行)

因此,我们的MainActivity.java如下所示:

package com.example.dataexchange;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

public class MainActivity extends ActionBarActivity {

SocketHandler server;

@Override
protected void onCreate(Bundle savedInstanceState) {

    Log.v("jlumme", "Main/ start network task");

    new Thread(new Runnable() {
        public void run() {
            server = new SocketHandler(6000);
            server.run();
        }
    }).start();

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        return rootView;
    }
}
}
package com.example.dataexchange;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import android.util.Log;

public class SocketHandler implements Runnable {

private Socket socket;
private ServerSocket server;
private PrintWriter out;
private BufferedReader in;

private int socketPort;
SocketHandler(int port) {
    socketPort = port;
}

@Override
public void run() {

    Log.v("jlumme", "Socket thread has started");
    String inputText;

    // TODO Auto-generated method stub
    try {
        Log.v("jlumme", "Starting socket server ");

        server = new ServerSocket(6000);
        socket = server.accept();

        Log.v("jlumme", "Client connected");

        out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); 
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                

        while ((inputText = in.readLine()) != null) {
            Log.v("jlumme", "Received:" + inputText);
            out.println("you wrote:" + inputText);
        }

        Log.v("jlumme", "connection established");

    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}
}
通常,我们只是在一个单独的线程中启动我们的
SocketHandler
类。SocketThread类如下所示:

package com.example.dataexchange;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

public class MainActivity extends ActionBarActivity {

SocketHandler server;

@Override
protected void onCreate(Bundle savedInstanceState) {

    Log.v("jlumme", "Main/ start network task");

    new Thread(new Runnable() {
        public void run() {
            server = new SocketHandler(6000);
            server.run();
        }
    }).start();

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        return rootView;
    }
}
}
package com.example.dataexchange;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import android.util.Log;

public class SocketHandler implements Runnable {

private Socket socket;
private ServerSocket server;
private PrintWriter out;
private BufferedReader in;

private int socketPort;
SocketHandler(int port) {
    socketPort = port;
}

@Override
public void run() {

    Log.v("jlumme", "Socket thread has started");
    String inputText;

    // TODO Auto-generated method stub
    try {
        Log.v("jlumme", "Starting socket server ");

        server = new ServerSocket(6000);
        socket = server.accept();

        Log.v("jlumme", "Client connected");

        out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); 
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                

        while ((inputText = in.readLine()) != null) {
            Log.v("jlumme", "Received:" + inputText);
            out.println("you wrote:" + inputText);
        }

        Log.v("jlumme", "connection established");

    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}
}
基本上,在
run()
方法中,您启动一个新的
SocketServer
,并开始等待客户端。一旦客户端连接,您将双向设置流缓冲区,并开始等待消息(任何以换行符结尾的内容,
'\n'
都可以)

在C#端,应用程序非常简单。它连接到
localhost
端口
6000
,并发送一行:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class SynchronousSocketClient
{

public static void StartClient() {
    // Data buffer for incoming data.
    byte[] bytes = new byte[1024];

    // Connect to a remote device.
    try {

        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6000);

        // Create a TCP/IP  socket.
        Socket sender = new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, ProtocolType.Tcp );

        // Connect the socket to the remote endpoint. Catch any errors.
        try {
            sender.Connect(remoteEP);

            Console.WriteLine("Socket connected to {0}",
                sender.RemoteEndPoint.ToString());

            // Encode the data string into a byte array.
            byte[] msg = Encoding.ASCII.GetBytes("This is a test\n");

            // Send the data through the socket.
            int bytesSent = sender.Send(msg);

            // Receive the response from the remote device.
            int bytesRec = sender.Receive(bytes);
            Console.WriteLine("Echoed test = {0}",
                Encoding.ASCII.GetString(bytes,0,bytesRec));

            // Release the socket.
            sender.Shutdown(SocketShutdown.Both);
            sender.Close();

        } catch (ArgumentNullException ane) {
            Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
        } catch (SocketException se) {
            Console.WriteLine("SocketException : {0}",se.ToString());
        } catch (Exception e) {
            Console.WriteLine("Unexpected exception : {0}", e.ToString());
        }

    } catch (Exception e) {
        Console.WriteLine( e.ToString());
    }
}

public static int Main(String[] args)
{
    StartClient();
    return 0;
}
}
如果在执行C#程序时,它将向客户端发送
这是一个测试
字符串,客户端将回显该字符串:

c:\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\bin\Debug>ConsoleApplication2.exe
Socket connected to 127.0.0.1:6000
Echoed test = you wrote:This is a test
我想在bounty关闭前到达截止日期,因此目前没有适当的消息处理,c#将立即退出(而Android端将对此感到困惑),对此我深表歉意。但我认为,一旦您运行了这个示例,您就可以轻松地将其扩展到您的需要,并实现必要的逻辑来处理终止和其他内容


希望能有所帮助

在我看来,这与NFC或第三种设备没有多大关系。你需要在你的电脑上安装一个程序,用USB线从安卓设备上读取数据。或者你想让Android设备向PC发送数据?@greenapps谢谢你的回复,先生。。是的,这就是我的目标。
C#
应该轮询连接的安卓设备收到的
NFC消息,或者连接的安卓设备在
收到NFC消息后应该
C#程序发送数据
有可能吗?你知道怎么做吗?为什么要用USB线连接?@greenapps我想C#应用程序用这种方式检索数据会更容易。还有其他可能/简单的方法吗?最简单的方法是wifi。只有服务器/客户端。如果你说C#应该检索数据,那么android上的数据存储/处理在哪里?