обнаружение wifidirect одних и тех же пиров несколько раз в фоновой службе

Я пытался обнаружить несколько одноранговых узлов - несколько раз в фоновой службе вместо активности. В целом на основе этого: http://developer.android.com/training/connect-devices-wireless/nsd-wifi-direct.html

Поскольку рекламируемая услуга однорангового узла, однажды полученная, не появляется снова, если этот одноранговый узел уходит и возвращается в зону действия. Причина, по которой мне нужно повторно обнаружить одни и те же сверстники, заключается в том, что я меняю значение записи TXT в зависимости от использования приложения. Что необходимо повторно объявить, и принимающее устройство обновляет локальный файл новыми значениями.

Несмотря на это, мне удалось заставить это работать ненадежным образом. Путем удаления localservice и serviceRequest и повторной инициации регистрации и обнаружения с помощью обработчика.

Но я заметил, что некоторые из более ранних рекламных объявлений объединяются и продолжают показываться, даже когда рекламное устройство прекратило рекламу, а прослушиватели TXT не подключаются и время от времени. Это приводит к игнорированию предупреждения WifiP2pManager при добавлении как локальной службы, так и запроса на обнаружение службы. Следовательно, слушатель время от времени не получает рекламу, но продолжает получать рекламу время от времени, даже когда Wi-Fi отключен.

01-06 17:14:34.324  26591-26591/com.cutting.chai.wifi D/WifiP2pManager﹕ Ignored { when=-25ms what=139313 target=android.net.wifi.p2p.WifiP2pManager$Channel$P2pHandler }
[ 01-06 17:14:34.324 26591:26591 D/Status] Added Local Service
01-06 17:14:34.324  26591-26591/com.cutting.chai.wifi D/WifiP2pManager﹕ Ignored { when=-25ms what=139313 target=android.net.wifi.p2p.WifiP2pManager$Channel$P2pHandler }
01-06 17:14:34.324  26591-26591/com.cutting.chai.wifi D/WifiP2pManager﹕ Ignored { when=-26ms what=139313 target=android.net.wifi.p2p.WifiP2pManager$Channel$P2pHandler }
[ 01-06 17:14:34.324 26591:26591 D/Status]  Added service discovery request

И ниже мой код:

public class WifiDirectDiscoverService extends Service{


public static final String TAG = "wifidirectservicedemo";

// TXT RECORD properties
public static final String TXTRECORD_PROP_AVAILABLE = "available";
public static final String SERVICE_INSTANCE = "_ccwifidirect";
public static final String SERVICE_REG_TYPE = "_presence._tcp";


private WifiP2pManager manager;


private final IntentFilter intentFilter = new IntentFilter();
private WifiP2pManager.Channel channel;
private BroadcastReceiver mReceiver;
private WifiP2pDnsSdServiceRequest serviceRequest;
WifiP2pDnsSdServiceInfo service;

/* Preferences to get user data to set the advertisement record */
private ccSharedPreferences sharedPreferences;
private String[] interestCodes;
private String[] hobbyCodes;


Handler mHandler = new Handler();


@Override
public IBinder onBind(Intent arg0) {

    return null;
}

public void onCreate() {
    super.onCreate();
    Log.d("Server", ">>>onCreate()");
}



final Runnable ToastRunnable = new Runnable(){
    public void run(){
        Toast.makeText(getApplicationContext(), "discover service",
                Toast.LENGTH_LONG).show();



        manager.removeLocalService(channel, service, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess () {
                appendStatus("Remove Local Service");
            }

            @Override
            public void onFailure ( int error){
                appendStatus("Failed to remove a service "+error);
            }
        });


        manager.removeServiceRequest(channel, serviceRequest, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                appendStatus("Clear Service Requests");
            }

            @Override
            public void onFailure(int error) {
                appendStatus("Failed to clear Service Requests "+error);
            }
        });


        startRegistration();
        setupListener();
        initiateDiscovery();

        mHandler.postDelayed(ToastRunnable, 15000);
    }
};


@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    super.onStartCommand(intent, startId, startId);

    intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
    intentFilter
            .addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
    intentFilter
            .addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);

    manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
    channel = manager.initialize(getApplicationContext(), getMainLooper(), null);

    mReceiver = new WiFiDirectBroadcastReceiver(manager, channel, WifiDirectDiscoverService.this);
    registerReceiver(mReceiver, intentFilter);

    startRegistration();
    setupListener();
    initiateDiscovery();

    mHandler.postDelayed(ToastRunnable, 10000);

    return START_STICKY;

}


/**
 * Registers a local service and then initiates a service discovery
 */
private void startRegistration() {

    sharedPreferences = new ccSharedPreferences();

    Map<String, String> record = new HashMap<>();



    record.put(TXTRECORD_PROP_AVAILABLE, "visible");



    int size = record.toString().length();


    Toast.makeText(getApplicationContext(), size + " bytes record ", Toast.LENGTH_LONG).show();

    service = WifiP2pDnsSdServiceInfo.newInstance(
            SERVICE_INSTANCE, SERVICE_REG_TYPE, record);

    manager.addLocalService(channel, service, new WifiP2pManager.ActionListener() {

        @Override
        public void onSuccess() {
            appendStatus("Added Local Service");
        }

        @Override
        public void onFailure(int error) {
            appendStatus("Failed to add a service "+error);
        }
    });

}

private void setupListener() {

    /*
     * Register listeners for DNS-SD services. These are callbacks invoked
     * by the system when a service is actually discovered.
     */

    WifiP2pManager.DnsSdTxtRecordListener txtListener = new WifiP2pManager.DnsSdTxtRecordListener() {

                    /**
                     * A new TXT record is available. Pick up the advertised
                     * buddy name.
                     */
                    @Override
                    public void onDnsSdTxtRecordAvailable(
                            String fullDomainName, Map<String, String> record,
                            WifiP2pDevice device) {


                        if (record.get(TXTRECORD_PROP_AVAILABLE) != null) {
                            Log.d(TAG,
                                    device.deviceName + " is "
                                            + record.get(TXTRECORD_PROP_AVAILABLE));

                            Toast.makeText(getApplicationContext(), device.deviceName + " is " + record.get(TXTRECORD_PROP_AVAILABLE), Toast.LENGTH_LONG).show();

                            Toast.makeText(getApplicationContext(), "Advertised Service is " + record.toString(), Toast.LENGTH_LONG).show();
                            Log.d("Record", record.toString());



                        }

                    }
                };


    WifiP2pManager.DnsSdServiceResponseListener servListener = new WifiP2pManager.DnsSdServiceResponseListener() {

        @Override
        public void onDnsSdServiceAvailable(String instanceName,
                                            String registrationType, WifiP2pDevice srcDevice) {

            // A service has been discovered. Is this our app?

            if (instanceName.equalsIgnoreCase(SERVICE_INSTANCE)) {

                // update the UI and add the item the discovered
                // device.

                WiFiP2pService service = new WiFiP2pService();
                service.device = srcDevice;
                service.instanceName = instanceName;
                service.serviceRegistrationType = registrationType;


                Log.d(TAG, "onBonjourServiceAvailable "
                        + instanceName);

                Toast.makeText(getApplicationContext(), service.device + " is around ", Toast.LENGTH_LONG).show();
                Toast.makeText(getApplicationContext(), instanceName + " is the instance name ", Toast.LENGTH_LONG).show();


            }

        }
    };




    manager.setDnsSdResponseListeners(channel, servListener, txtListener);


}

public void initiateDiscovery(){
    // After attaching listeners, create a service request and initiate
    // discovery.
    serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
    manager.addServiceRequest(channel, serviceRequest,
            new WifiP2pManager.ActionListener() {

                @Override
                public void onSuccess() {
                    appendStatus("Added service discovery request");
                }

                @Override
                public void onFailure(int arg0) {
                    appendStatus("Failed adding service discovery request "+arg0);
                }
            });

    manager.discoverServices(channel, new WifiP2pManager.ActionListener() {

        @Override
        public void onSuccess() {
            appendStatus("Service discovery initiated");
        }

        @Override
        public void onFailure(int arg0) {
            appendStatus("Service discovery failed "+arg0);

        }
    });

}

public void appendStatus(String status) {
    Log.d("Status" + "\n", status);
}

@Override
public void onDestroy() {
    Toast.makeText(this, "service onDestroy", Toast.LENGTH_LONG).show();
    mHandler.removeCallbacksAndMessages(null);
}
}

Я также прочитал это: Отправка данных в Обнаружение службы Android WiFi Direct вместо подключения

Хотя я понимаю, что ненадежность использования многоадресного DNS-обнаружения в основном предназначена для обнаружения служб, а не для сценариев обмена сообщениями. В моем случае значение записи меняется не очень часто. Но мне нужно убедиться, что объявление и обнаружение, а также несколько одноранговых узлов происходят без ошибочного поведения, как описано.

Любая помощь в этом очень ценится!

Спасибо!

Арнаб


person Arnab Saha    schedule 06.01.2016    source источник
comment
Подтвердили ли вы поведение: поскольку рекламируемая услуга однорангового узла, однажды полученного, не появляется снова, если этот одноранговый узел уходит и возвращается в зону действия, я видел, как услуги обнаруживались несколько раз, даже если они не исчезают. Другие наблюдения в основном вызваны действительно ненадежной реализацией API, насколько я знаю, вы мало что можете сделать, чтобы улучшить его.   -  person Dr.Jukka    schedule 08.01.2016
comment
Привет, @Dr.Jukka, спасибо за ответ. Подтвердили ли вы поведение: поскольку рекламируемая услуга однорангового узла, однажды полученная, не появляется снова, если этот одноранговый узел уходит и возвращается в зону действия. Он снова обнаруживает службу, но иногда возникают задержки или неустойчивое поведение. Я работал над другой реализацией, используя эту оболочку github.com/markrjr/Salut и расширив ее для использования в сервис. Честно говоря, с этим лучше производительность, но большинство других наблюдений действительно появляются время от времени, чувак, в реализации API, я полагаю, как вы упомянули.   -  person Arnab Saha    schedule 11.01.2016
comment
Привет @Dr.Jukka, я случайно подписался на ваш github и узнал о thaliproject и вашем вкладе в него. thaliproject.org/Alumni, в котором упоминается, что прямой Wi-Fi не лучший вариант для Android. Я тоже понял ограничения API в части обнаружения и просматривал github.com/thaliproject/BTConApp. . Хотел узнать ваше мнение о возможности использования прямого подключения Wi-Fi для передачи данных вместо Bluetooth или ble? Были ли какие-либо известные ограничения/недостатки с прямым Wi-Fi соединением, которые вы изучаете?   -  person Arnab Saha    schedule 19.01.2016
comment
По сути, с Thali им нужно было установить соединение без взаимодействия с пользователем, поэтому они выбрали небезопасный Bluetooth на Android. Прямое соединение Wi-Fi позволит осуществлять связь на основе IP с более высокой скоростью передачи данных, но на самом деле оно также требует взаимодействия с пользователем при первоначальном сопряжении.   -  person Dr.Jukka    schedule 19.01.2016
comment
Спасибо за помощь! Я также смотрю на установление соединения без взаимодействия с пользователем. И пытались реализовать аналогичный подход, как с библиотекой BTConApp. Но из того, что я заметил, существует несколько подключений с одного устройства к устройству-получателю. В случаях, когда я хочу узнать некоторую информацию об устройстве между, например. 3 устройства, в идеале в лучшем случае одно устройство будет делать 2 подключения к двум другим устройствам при отправке данных. Делаем в общей сложности 6 подключений. Итак, n^n-1 соединений. Можно ли сделать соединения двунаправленными для оптимизации?   -  person Arnab Saha    schedule 26.01.2016
comment
По сути, после того, как вы установили конвейер, вы действительно можете шлифовать данные в обоих направлениях. В любом случае, обратите внимание, что я не проверял какие-либо коды с помощью Marshmallow, поэтому могут быть некоторые общие проблемы со связью в этих версиях ОС, о которых я не знаю.   -  person Dr.Jukka    schedule 26.01.2016
comment
Большое спасибо! смог отправить данные в обоих направлениях, передав их в методы sayHi() и sayAck(). Кроме того, смог заставить его работать и с зефиром. Следуйте сценарию: Тестовый сценарий: Устройства: Moto E (1-го поколения) (Пользовательская прошивка 5.1) Nexus 4 (Стандартная 5.1.1) Nexus 6 (Стандартная 5.1) Nexus 7 (Пользовательская прошивка 6.0) Результаты: Moto E, Nexus 4 и Nexus 6 , эти 3 устройства обнаружили друг друга при одном подключении менее чем за 1,40 минуты. Nexus 7 (Marshmallow) появился после того, как были обнаружены все остальные, и обнаружил остальные 3 устройства. И все закончили встречаться примерно через 3,3 минуты.   -  person Arnab Saha    schedule 28.01.2016
comment
Привет, @Dr.Jukka, у меня есть еще один быстрый вопрос о небезопасном соединении bt. Есть ли способ увеличить диапазон с этим? Например, как можно настроить уровень мощности RSSI/TX в BLE для более дальнего действия?   -  person Arnab Saha    schedule 29.01.2016