私は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...) と呼ばれるコールバックのみを取得します。
そして、古いサービスを取得するということは、私が常にそれらをクリアするときに奇妙です (私はサービスレコードデータにタイムスタンプを含めており、最後以外はいつでも破棄できますが、論理的ではないようです)。
何か案は?アプリケーションを書くことはもはや面白くないので、どんな助けも非常に高く評価されます (:-)=
どうもありがとう!