android在不同的设备上传输两个应用程序

android在不同的设备上传输两个应用程序,android,communication,Android,Communication,这里的所有问题都指向同一个应用程序的类,或者在同一个设备中处于不同进程中的不同应用程序的类。我想在两个不同的设备上向两个不同的应用程序发送数据。我试着用广播接收机,但没用。这是我发送数据的代码片段 addressstring = String.valueOf(acrilocation.getText()); if (addressstring != null && addressstring.length() > 0){ In

这里的所有问题都指向同一个应用程序的类,或者在同一个设备中处于不同进程中的不同应用程序的类。我想在两个不同的设备上向两个不同的应用程序发送数据。我试着用广播接收机,但没用。这是我发送数据的代码片段

addressstring = String.valueOf(acrilocation.getText());
            if (addressstring != null && addressstring.length() > 0){
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SEND);
            intent.putExtra(Constants.LOCATION_DATA_EXTRA, addressstring);
            intent.setType("text/plain");
            sendBroadcast(intent);
            } else{
                Toast.makeText(getApplicationContext(), "Enter valid location address", Toast.LENGTH_SHORT).show();
            }
但是,当我使用下面的代码片段在我的另一个应用程序中接收到数据时,它失败了。当我调试应用程序时,我得到空异常

Intent intent = getIntent();
        String action = intent.getAction();
        String data = intent.getStringExtra(Intent.EXTRA_INTENT);
        String type = intent.getType();
        useraddress.setText(data);
           startActivity(intent);

有没有其他方法可以做到这一点?我的意思是向安装在另一台设备上的另一个应用程序发送数据,并从中发送数据?

通过接受传入套接字连接的网络进行连接

在Android设备之间(或任何对等设备之间)执行此操作的常用方法是使用套接字

您将一个或两个设备设置为“侦听”套接字上的连接,然后在它们想要通信时接受另一个设备的连接(或者您可以使用专用的客户端和服务器,客户端始终启动连接)

一旦建立连接,您就可以来回发送消息

Android客户端服务器套接字应用程序有很多例子,但我发现其中一个很有用:

  • (及其附带的服务器端博客文章-客户端博客中包含的链接)
请注意,您可能需要在此基础上添加自己的“协议”-例如,如果您发送的文件长度未知,但没有任何特殊的“结束”字符,则可能需要添加一个字节(或多个字节以表示int、long等)在开始时,指示传输的长度,以便接收方知道何时接收到所有信息(或在发生错误时未接收到所有信息)


通过不允许传入连接的网络连接(例如,大多数3G/4G)

在这些场景中,虽然理论上没有什么能阻止套接字工作,但实际上许多移动运营商不允许传入套接字连接。此外,您还需要找到移动设备的公共IP地址,这是可能的,但非常复杂。如果您的解决方案只在单一运营商网络上运行,您可以进行试验,看看它是否有效,但如果无效,您可能会发现使用“中间”服务器更好、更容易:

  • 设备A连接到服务器
  • 设备B连接到服务器
  • 设备A向服务器请求已连接设备的地址并“发现”设备B
  • 设备A为设备B发送消息。它实际将消息发送到服务器,并指示将发送到设备B
  • 服务器通知设备B有一条消息可供其使用(例如使用某种消息通知,如Google Cloud Messaging,或者通过设备定期轮询查看是否有任何消息)
  • 设备B从服务器检索消息

以上内容适用于几乎所有允许连接到internet的网络。它的缺点是需要一台服务器,但在大多数移动网络中,这可能是一种必要的方法。

如果您想让位于世界不同地区的两台不同设备上的Android应用程序的两个实例在没有服务器的情况下直接相互通信,那么最好的方法就是使用隐藏服务。Tor隐藏服务允许应用绕过防火墙或NAT(当然,如果Tor没有被阻止的话),并且设备可以轻松地相互通信,而无需中央服务器。在这里,我将尝试给出一些您可以尝试的代码示例。适合这种材料的最好的图书馆是

步骤1:将依赖项添加到gradle.build-in-app模块:

步骤2:向清单文件添加权限(Internet权限或其他权限)

步骤3(i):现在我们将用Java编写经典的客户机-服务器程序,但添加了Android和Tor风格。要正确地测试这一点,请尝试创建两个不同的应用程序。一个应用程序将是服务器,另一个应用程序将是客户端。您甚至可以在不同的手机上安装这两个应用程序。 在本例中,我们将尝试从客户端应用程序向服务器应用程序发送“Hello from Tor client”字符串

对于服务器端:您可以在任何活动和异步任务中尝试此功能

    void server(Context context){
            //For comments and documentation, visit the original repo
            //https://github.com/thaliproject/Tor_Onion_Proxy_Library
            String fileStorageLocation = "hiddenservicemanager";;
            com.msopentech.thali.toronionproxy.OnionProxyManager onionProxyManager =
                    new com.msopentech.thali.android.toronionproxy.AndroidOnionProxyManager(context, fileStorageLocation);
            int totalSecondsPerTorStartup = 4 * 60;
            int totalTriesPerTorStartup = 5;
            try {
                boolean ok = onionProxyManager.startWithRepeat(totalSecondsPerTorStartup, totalTriesPerTorStartup);
                if (!ok)
                    System.out.println("Couldn't start tor");

                while (!onionProxyManager.isRunning())
                    Thread.sleep(90);
                System.out.println("Tor initialized on port " + onionProxyManager.getIPv4LocalHostSocksPort());

                int hiddenServicePort = 8080;
                int localPort = 9343;
                String onionAddress = onionProxyManager.publishHiddenService(hiddenServicePort, localPort);
                System.out.println("Tor onion address of the server is: "+onionAddress);
                ServerSocket serverSocket = new ServerSocket(localPort);
                while(true) {
                    System.out.println("Waiting for client request");
                    Socket receivedSocket = serverSocket.accept();
                    ObjectInputStream ois = new ObjectInputStream(receivedSocket.getInputStream());
                    String message = (String) ois.readObject();

                    //Here we will print the message received from the client to the console.
                    /*You may want to modify this function to display the received
                    string in your View.*/
                    System.out.println("Message Received: " + message);
                }
            }
            catch (Exception e) {
                e.printStackTrace();

            }
    }
步骤3(ii):对于客户端,请尝试此功能

//Inputs:
//'String onionAddress' should be the one obtained in server() function.
//It will be printed in the console and it will possibly remain the same 
//even if the app restarts, because all the data/cache will be stored locally.
//Also, when you run the code for the first time, Tor will take about 1 or 2 mins
//to bootstrap. In the subsequent runs, Tor will start relatively faster as the
//data will be cached. 'int hiddenServicePort' is the port at which the hidden
//service has started on the server. In our example code, it is 8080. So, pass that here
void client(Context context, String onionAddress, int hiddenServicePort){
        String fileStorageLocation = "clientmanager";
        com.msopentech.thali.toronionproxy.OnionProxyManager onionProxyManager =
                new com.msopentech.thali.android.toronionproxy.AndroidOnionProxyManager(context, fileStorageLocation);
        int totalSecondsPerTorStartup = 4 * 60;
        int totalTriesPerTorStartup = 5;
        try {
            boolean ok = onionProxyManager.startWithRepeat(totalSecondsPerTorStartup, totalTriesPerTorStartup);
            int socksPort=onionProxyManager.getIPv4LocalHostSocksPort();
            if (!ok)
                System.out.println("Couldn't start tor in client");

            while (!onionProxyManager.isRunning())
                Thread.sleep(90);
            System.out.println("Client Tor initialized on port " + socksPort);
            System.out.println("Client is waiting for the server to get ready");
            Thread.sleep(2000);
            Socket clientSocket =
                    Utilities.socks4aSocketConnection(onionAddress, hiddenServicePort, "127.0.0.1", socksPort);
            ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
            oos.writeObject("Hello from Tor client\n");
            System.out.println("Client has sent the message");
            oos.close();
        }
        catch (Exception e) {
            e.printStackTrace();

        }
}
完成了。运行应用程序并进行测试。如果你陷入困境,试试咨询


因此,现在您的应用程序可以在没有任何中央服务器的情况下进行通信。在这些使用案例中,Tor隐藏服务非常棒。

您也可以使用IP6,然后您可以从一部手机直接连接到另一部手机。我发现不同4G运营商的两部手机之间的延迟低至60毫秒(尽管是在同一个国家)。请注意,您必须发送一些数据,以避免降低开关速度以获得如此低的延迟。10磅对我来说已经足够了

侦听端根本不需要任何更改,客户端只需使用IP6地址: s=新插座(“2a10:811:21c:22a1:7683:ae1:18c7:9827”,9343)


IP6似乎得到了许多运营商的支持。如果不是,tor可以是一个很好的后备方案,如果延迟不是问题。

这应该如何工作?广播s用于系统通信。一个应用程序如何知道其他设备上的另一个应用程序?您必须使用网络或蓝牙或类似的方式进行数据传输。非常感谢您的回答。然而,我的问题是,这些设备不会在同一个wi-fi网络上。他们将彼此相距数英里。这个解决方案有效吗?是的,只要您知道每个设备的公共IP地址(或URL),它就有效。你还需要知道任何防火墙问题。这听起来像是我问题的解决方案,因此我将接受它作为答案。我正在试图弄清楚如何获得ser的ip
//Inputs:
//'String onionAddress' should be the one obtained in server() function.
//It will be printed in the console and it will possibly remain the same 
//even if the app restarts, because all the data/cache will be stored locally.
//Also, when you run the code for the first time, Tor will take about 1 or 2 mins
//to bootstrap. In the subsequent runs, Tor will start relatively faster as the
//data will be cached. 'int hiddenServicePort' is the port at which the hidden
//service has started on the server. In our example code, it is 8080. So, pass that here
void client(Context context, String onionAddress, int hiddenServicePort){
        String fileStorageLocation = "clientmanager";
        com.msopentech.thali.toronionproxy.OnionProxyManager onionProxyManager =
                new com.msopentech.thali.android.toronionproxy.AndroidOnionProxyManager(context, fileStorageLocation);
        int totalSecondsPerTorStartup = 4 * 60;
        int totalTriesPerTorStartup = 5;
        try {
            boolean ok = onionProxyManager.startWithRepeat(totalSecondsPerTorStartup, totalTriesPerTorStartup);
            int socksPort=onionProxyManager.getIPv4LocalHostSocksPort();
            if (!ok)
                System.out.println("Couldn't start tor in client");

            while (!onionProxyManager.isRunning())
                Thread.sleep(90);
            System.out.println("Client Tor initialized on port " + socksPort);
            System.out.println("Client is waiting for the server to get ready");
            Thread.sleep(2000);
            Socket clientSocket =
                    Utilities.socks4aSocketConnection(onionAddress, hiddenServicePort, "127.0.0.1", socksPort);
            ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
            oos.writeObject("Hello from Tor client\n");
            System.out.println("Client has sent the message");
            oos.close();
        }
        catch (Exception e) {
            e.printStackTrace();

        }
}