2

私はAndroidプログラミングにかなり慣れていません。しかし、私はこれに1週間以上取り組んでおり、騒ぎ始めています.

私の考えは、Wifi Direct を使用して 2 つのデバイスを接続したいということです。しかし、アプリケーションを実行しているものにのみ接続したいのです。また、WifiP2pDevice に含まれる MAC や Android_XXXX 名だけでなく、他のデバイスの情報 (ユーザー名など) をユーザーが確認できるようにしたいと考えています。そのため、他のデバイスを探しているデバイスは、アプリケーション サービスを開始し、このサービスをブロードキャストしているピアを検索する必要があると判断しました。

問題 (私は 2 つの実際のデバイスでテストしています) は、まったく同じコードを実行しているにもかかわらず、そのうちの 1 つだけがサービス検出コールバック (以下の onDnsSd... リスナー) を取得していることです。したがって、一方は適切に機能しますが、他方はそうではありません。さらに、「古い」サービスを取得しています。つまり、サービスを開始するたびに (以前に開始したサービスをキャンセルしても)、そのサービスは少なくとも数分間はまだブロードキャストされているようです。

コードの短縮版を含めます。

public class MoveFlufietsDialogFragment extends DialogFragment implements ChannelListener, DeviceActionListener {

    public final HashMap<String, FlufietsPeer> mBuddies = new HashMap<String, FlufietsPeer>();

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
    ...
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);

        mManager = (WifiP2pManager) getActivity().getSystemService(Context.WIFI_P2P_SERVICE);
        mChannel = mManager.initialize(getActivity(), getActivity().getMainLooper(), null);
        ...
        startRegistration();
        discoverFlufietsService();
        ...
    }


    public void discoverFlufietsService() {
        DnsSdTxtRecordListener txtListener = new DnsSdTxtRecordListener() {
            @Override
            public void onDnsSdTxtRecordAvailable(String fullDomain, Map record, WifiP2pDevice device) {
                // This and the next listener are only called in one of the devices.
                String serviceName = (String) record.get("serviceName");
                if ((serviceName != null) && (serviceName.equals("flufiets")) {
                    // I put the record data in the mBuddies HashMap.
                    ...
                    mBuddies.put(device.deviceAddress, myPeerDataStructure);
                }
            }
        };

        DnsSdServiceResponseListener servListener = new DnsSdServiceResponseListener() {
            @Override
            public void onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice resourceType) {
                if (mBuddies.containsKey(resourceType.deviceAddress)) {
                    FlufietsPeer flufietsPeer = mBuddies.get(resourceType.deviceAddress);
                    WiFiPeerListAdapter adapter = ((WiFiPeerListAdapter) mFragmentList.getListAdapter());
                    adapter.add(flufietsPeer);
                    adapter.notifyDataSetChanged();
                }
            }
        };

        mManager.setDnsSdResponseListeners(mChannel, servListener, txtListener);

        WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
        mManager.addServiceRequest(mChannel, serviceRequest, new ActionListener() {
            // onSuccess/onFailure toasts.
        });

        mManager.discoverServices(mChannel, new WifiP2pManager.ActionListener() {
            // onSuccess/onFailure toasts.
        });
    }

    public void startRegistration() {
        mManager.clearLocalServices(mChannel, new ActionListener() {
            // onSuccess/onFailure toasts.
        });

        Map record = new HashMap();
        record.put("serviceName", "flufiets");
        ...

        WifiP2pDnsSdServiceInfo serviceInfo = WifiP2pDnsSdServiceInfo.newInstance(flufietsService, "_tcp", record);

        mManager.addLocalService(mChannel, serviceInfo, new ActionListener() {
            // onSuccess/onFailure toasts.
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
        getActivity().registerReceiver(mReceiver, mIntentFilter);
    }

    @Override
    public void onPause() {
        super.onPause();
        getActivity().unregisterReceiver(mReceiver);
    }

    @Override
    public void onStop() {
        super.onStop();
        mManager.clearLocalServices(mChannel, new ActionListener() {
            // onSuccess/onFailure toasts.
        });
    }

    ...
}

この問題は、デバイス自体に関連していないようです (動作する場合もあれば、動作しない場合もありますが、常にそのうちの 1 つだけです)。私たち自身がブロードキャストしているサービスを見つけようとしているか、2 つのデバイスで同じサービスを提供していることに関係していると思われます。各デバイスが「送信」または「受信」サービスを提供するようにサービスの名前を変更しようとしましたが、機能しません。デバイスの 1 つで (onDnsSd...) と呼ばれるコールバックのみを取得します。

そして、古いサービスを取得するということは、私が常にそれらをクリアするときに奇妙です (私はサービスレコードデータにタイムスタンプを含めており、最後以外はいつでも破棄できますが、論理的ではないようです)。

何か案は?アプリケーションを書くことはもはや面白くないので、どんな助けも非常に高く評価されます (:-)=

どうもありがとう!

4

1 に答える 1

0

後でローカル サービスを追加する前に、clearLocalService 呼び出しが成功するまで待つ必要があります。そのため、addLocalService 呼び出しを clearLocalServices の onSuccess コールバックに入れます。

于 2014-01-28T05:30:11.467 に答える