android связывает два приложения на разных устройствах


Все вопросы здесь указывают на классы одного и того же приложения или разных приложений в отдельных процессах, но в одном и том же устройстве. Я хотел бы отправлять данные в два отдельных приложения и с двух разных устройств. Я попробовал использовать 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();
            }
Но когда я получаю данные в другом приложении, используя следующий фрагмент кода, это не удается. Когда я отлаживаю приложение, я получаю нулевое исключение.
Intent intent = getIntent();
        String action = intent.getAction();
        String data = intent.getStringExtra(Intent.EXTRA_INTENT);
        String type = intent.getType();
        useraddress.setText(data);
           startActivity(intent);

Есть ли другой способ достичь вот это? Я имею в виду, чтобы отправлять данные и из другого приложения, которое установлено в другом устройстве?

2 10

2 ответа:

Подключение по сетям, принимающим входящие сокетные соединения

Обычный способ сделать это между устройствами Android (или между любыми одноранговыми устройствами) - использовать сокеты.

Вы настраиваете одно или оба устройства для "прослушивания" соединений на сокете, а затем принимаете соединение от другого, когда они хотят общаться (или у вас может быть выделенный клиент и сервер, и клиент всегда инициирует соединения).

Как только соединение установлено, вы можете отправляйте сообщения туда и обратно.

Есть много примеров приложений сокетов клиент-сервер Android, но один из них я нашел полезным:

Обратите внимание, что вам, возможно, придется добавить свой собственный "протокол" поверх этого - например, если вы отправляете файл неизвестной длины без какого-либо специального символа "конец", вы можете захотеть чтобы добавить байт (или несколько байт для представления int, long и т. д.) В начале, чтобы указать длину передачи, чтобы принимающая сторона знала, когда она получила все (или что она не получила все в случае ошибки).

Подключение по сетям, которые не позволяют входящие соединения (например, большинство 3G/4G)

В этих сценариях, хотя теоретически ничто не останавливает работу сокетов, на практике многие мобильные операторы не разрешают входящий разъемные соединения. Кроме того, вам нужно будет найти публичный IP-адрес мобильного телефона, что возможно, но является дополнительной сложностью. Если ваше решение когда-либо будет работать только на одной сети операторов, вы можете поэкспериментировать и посмотреть, работает ли оно, но если нет, вы можете найти его лучше и проще использовать сервер в "середине":

  • Устройство a подключается к серверу
  • Устройство B подключается к серверу
  • устройство а запрашивает у сервера адреса подключенных устройств и "обнаруживает" устройство B
  • Устройство A отправляет сообщение для устройства B. оно фактически отправляет сообщения на сервер с указанием, что оно должно быть отправлено устройству B
  • сервер уведомляет устройство B о том, что для него доступно сообщение (используя какое-либо уведомление о сообщении, например Google Cloud Messaging, или просто регулярно опрашивая устройства, чтобы узнать, есть ли у них какие-либо сообщения).
  • Устройство B получает сообщения от сервера

Вышесказанное будет работать в значительной степени любая сеть, которая позволяет подключиться к интернету. У него есть недостаток, требующий сервера, но это, вероятно, необходимый подход в большинстве мобильных сетей.

Если вы хотите, чтобы два экземпляра вашего Android-приложения на двух разных устройствах, расположенных в разных частях мира, напрямую взаимодействовали друг с другом без сервера, то лучший способ сделать это-использовать скрытые сервисы Tor. Скрытые сервисы Tor позволяют приложениям обходить брандмауэр или NAT (если Tor не заблокирован, конечно), и устройства могут легко взаимодействовать друг с другом без необходимости центрального сервера. Здесь я постараюсь привести несколько примеров кода, которые вы можете пробовать. Лучшая библиотека, подходящая для этого материала, - этоthis .

Шаг 1 : добавьте зависимости в свой gradle.build in app module:

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 : добавьте разрешения (разрешения интернета или что-то еще) в файл манифеста.

Шаг 3 (i): Теперь мы просто напишем классические клиент-серверные программы на Java, но с добавлением Android и Tor. Чтобы проверить это должным образом, попробуйте создать два разных приложения. Одним из приложений будет сервер и другое приложение будут клиентом. Предпочтительно, вы даже можете установить эти два приложения на разных телефонах. В этом примере мы попытаемся отправить строку "Hello from Tor client" из клиентского приложения в серверное приложение.

для серверной части: вы можете попробовать эту функцию внутри любого действия и 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();

        }
}

Дело сделано. Запускайте свои приложения и тестируйте их. Если вы застряли, попробуйте проконсультироваться здесь .

Итак, теперь ваши приложения могут взаимодействовать без центрального сервера. Скрытые сервисы Tor настолько удивительны в этих случаях использования.