android在不同的设备中通信两个应用程序

时间:2015-03-13 19:20:38

标签: android communication

此处的所有问题都指向相同应用的类或不同应用中的同一设备中的不同应用。我想在两个独立的设备中向两个独立的应用程序发送数据。我尝试使用broadcastreceiver,但它没有用。这是我发送数据的代码段。

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();
            }

但是当我使用以下代码段在我的其他应用中收到数据时,它失败了。当我调试应用程序时,我得到null异常。

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

还有另一种方法可以达到这个目的吗?我的意思是与另一个安装在另一个设备上的应用程序之间发送数据?

3 个答案:

答案 0 :(得分:5)

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

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

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

建立连接后,您可以来回发送消息。

Android客户端服务器套接字应用程序有很多例子,但我认为有用的是:

请注意,您可能必须在此基础上添加自己的“协议” - 例如,如果您发送的文件长度未知且没有任何特殊的“结束”字符,您可能需要添加一个字节(或几个字节)在开始时表示int,long等)以指示传输的长度,以便接收方知道它何时收到了所有内容(或者在发生错误时它没有收到所有内容)。

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

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

  • 设备A连接到服务器
  • 设备B连接到服务器
  • 设备A向服务器询问已连接设备的地址并“发现”设备B
  • 设备A为设备B发送消息。它实际上将消息发送到服务器,并指示它将被发送到设备B
  • 服务器通知设备B有消息可用(例如,使用某种类型的消息通知,例如Google Cloud Messaging,或者只是定期轮询设备以查看是否有消息)。
  • 设备B从服务器检索消息

以上几乎适用于任何允许连接互联网的网络。它确实有需要服务器的缺点,但它可能是大多数移动网络的必要方法。

答案 1 :(得分:1)

如果您希望Android应用程序的两个实例在世界不同地区的两个不同设备上直接相互通信而无需服务器,那么最好的方法是使用Tor隐藏服务。 Tor隐藏服务允许应用程序绕过防火墙或NAT(当然,如果Tor没有被阻止),并且这些设备可以轻松地彼此通信,而无需中央服务器。在这里,我将尝试给出一些代码示例,供您尝试。最适合此类应用的库是this

步骤1 :在 app 模块中的 gradle.build 中添加依赖项:

allprojects {
    repositories {
    maven { url 'https://jitpack.io' }
    }
}
dependencies {
    compile 'com.github.jehy:Tor-Onion-Proxy-Library:0.0.7'
    compile 'org.slf4j:slf4j-api:1.7.7'
    compile 'org.slf4j:slf4j-android:1.7.7'
}

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

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

对于服务器端:您可以在任何Activity和AsyncTask中尝试使用此功能。

    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();

        }
}

完成了。运行您的应用程序并进行测试。如果遇到问题,请尝试咨询here

因此,现在您的应用无需任何中央服务器即可进行通信。在这些用例中,Tor隐藏服务是如此出色。

答案 2 :(得分:0)

您也可以使用IP6,然后可以从一部电话到另一部电话进行直接套接字连接。我在不同4G运营商(虽然在同一国家)的两部手机之间的等待时间低至60毫秒。请注意,您必须发送一些数据,以免切换到较低速度以获得如此低的延迟。 10个并发ping对我来说足够了。

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

许多运营商似乎都支持IP6。如果不是这样,如果延迟不是问题,tor可能是一个很好的后备。