我已经在这个问题上搞砸了大约 2 个月了。
我正在定制的 android 板上构建一个应用程序,它将充当 wifi 显示器 (WFD)。当我启动电路板时,我可以轻松地连接几部不同的手机(LG Optimus G、LG Optimus G pro、三星 S3 和 S4)。连接并观看连接到自定义板的电视屏幕上复制的屏幕后,我可以断开连接,如果我在 2 分钟内重新连接,我可以再次连接。
如果我启动电路板(或断开连接)然后等待 2 分钟,设备将不再看到电话,电话有时会看到电路板,有时看不到。如果手机看到板子,我可以发起连接,但我无法连接成功。
我尝试了各种选择,但似乎没有一个可行。
该板在 AOSP 4.2.2 上运行
我现在有一些复杂的代码,它每 40 秒重新启动一次 discoverPeers 函数,通常它会在 30 秒后停止。除此之外,我禁用 WFD 并重新启用它,中间有 4 秒的延迟。
我还尝试禁用和重新启用 p2p 和频道,但都没有结果。
下面是我的代码,接收器在一个单独的类中。
@Override
protected void onCreate(Bundle savedInstanceState)
{
Settings.System.putInt(getContentResolver(), Settings.System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_NEVER);
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
setContentView(R.layout.wifi_direct_discovery);
connectPicture = findViewById(R.id.LinearLayout1);
Log.d(TAG, "onCreate");
isConnecting = false;
localWifiP2pWfdInfo = new WifiP2pWfdInfo();
localWifiP2pWfdInfo.setWfdEnabled(true);
localWifiP2pWfdInfo.setDeviceType(1);
localWifiP2pWfdInfo.setSessionAvailable(true);
localWifiP2pWfdInfo.setControlPort(7236);
localWifiP2pWfdInfo.setMaxThroughput(50);
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
wl.acquire();
super.onCreate(savedInstanceState);
}
@Override
public void onPeersAvailable(WifiP2pDeviceList peers)
{
List<WifiP2pDevice> peersList = new ArrayList<WifiP2pDevice>();
final ArrayList<String> list = new ArrayList<String>();
final ListView listview = (ListView) findViewById(R.id.deviceListView);
peersList.clear();
peersList.addAll(peers.getDeviceList());
if (peersList.size() == 0)
{
Log.d(TAG, "No devices found");
list.clear();
if ((pd != null) && pd.isShowing() && (isConnecting == false))
{
pd.dismiss();
Log.d(TAG, "Closed connecting dialog, restarting P2P");
Toast.makeText(this, "Connection failed please try again", Toast.LENGTH_LONG).show();
restartP2p(false);
}
else if (isConnecting == false)
{
restartP2p(false);
}
listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_black_text, R.id.list_content, list));
return;
}
else
{
int i = 0;
boolean found = false;
for (i = 0; i < peersList.size(); i++)
{
Log.d(TAG, "Found device: " + peersList.get(i).toString());
list.add(peersList.get(i).deviceName);
if ((pd != null) && pd.isShowing())
{
if (peersList.get(i).deviceAddress.equalsIgnoreCase(client.deviceAddress))
{
found = true;
}
}
}
if (!found)
{
if ((pd != null) && pd.isShowing())
{
Log.d(TAG, "Failed to find current client: closed connecting dialog, restarting P2P");
Toast.makeText(this, "Disconnected please try again", Toast.LENGTH_LONG).show();
restartP2p(false);
}
else
{
Log.d(TAG, "Failed to find current client, but we weren't trying to connect");
}
}
}
listview.setAdapter(new ArrayAdapter<String>(this, R.layout.list_black_text, R.id.list_content, list));
}
@Override
public void onConnectionInfoAvailable(WifiP2pInfo p2pInfo)
{
if (p2pInfo.isGroupOwner)
{
stopP2PDispeerTimeoutThread();
Log.d(TAG, "Connected as group owner");
int i = p2pInfo.mWfdRtspPort;
Log.d(TAG, "------------------------- onConnectionInfoAvailable rtsp port = " + i);
// get the ip addres from the connected client. Mac address is in
// client
String sourceIP = null;
while (sourceIP == null)
{
sourceIP = getIPFromMac(client.deviceAddress);
millisleep(250);
if (sourceIP == null)
{
Log.e(TAG, "Failed to get client address!!!!! from " + client.deviceAddress);
}
}
if (i == 0)
{
// this is not a wfd source, so let's get into client mode for
// upgrade etc.
Log.e(TAG, "This device is not a WFD source, so switch to client mode, device = "
+ client.deviceAddress);
}
else
{
Log.d(TAG, "Start connect to source : " + sourceIP);
if ((pd != null) && pd.isShowing())
pd.dismiss();
// need to stop the connection timeout thread here..
stopConnectTimeoutThread();
Intent intent = new Intent(getBaseContext(), WFDPlayActivity.class);
intent.putExtra("SOURCE_IP", sourceIP);
intent.putExtra("RTSPPORT", i);
startActivityForResult(intent, 210);
}
}
else
{
Log.e(TAG, "Connected as peer, this is very very wrong!!!!, restartP2P");
restartP2p(false);
startP2PDispeerTimeoutThread(34);
}
}
@Override
public void onConnectionRequested(WifiP2pDevice arg0, WifiP2pConfig arg1)
{
Log.d(TAG, "------------------------------------- onConnectionRequested");
stopP2PDispeerTimeoutThread();
isConnecting = true;
client = arg0;
if ((pd != null) && (pd.isShowing()))
{
pd.dismiss();
}
if (client != null)
{
createConnectionProgressDialog(client.deviceName);
}
}
public void onResume()
{
if (first_time == false)
{
Log.d(TAG, "onResume");
intentFilter.addAction("android.net.wifi.p2p.STATE_CHANGED");
intentFilter.addAction("android.net.wifi.p2p.PEERS_CHANGED");
intentFilter.addAction("android.net.wifi.p2p.CONNECTION_STATE_CHANGE");
intentFilter.addAction("android.net.wifi.p2p.THIS_DEVICE_CHANGED");
registerReceiver(receiver, intentFilter);
if (!mP2PDispeerThread.isRunning)
startP2PDispeerTimeoutThread(34);
manager.setDialogListener(channel, this);
manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
{
@Override
public void onSuccess()
{
Log.d(TAG, "discoverPeers success");
}
@Override
public void onFailure(int reasonCode)
{
Log.d(TAG, "discoverPeers failed");
}
});
}
else
{
Log.d(TAG, "onResume, first time");
restartP2p(first_time);
first_time = false;
}
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
super.onResume();
}
public void restartP2p(boolean first)
{
if (first)
{
mWifiManager = ((WifiManager) getSystemService("wifi"));
mWifiManager.setWifiEnabled(true);
sleep(4); // was 4
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);
manager.enableP2p(channel);
sleep(3); // was 3
mDisplayManager = ((DisplayManager) getSystemService("display"));
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);
mlock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF , "LockTag");
mlock.acquire();
instance = this;
receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
registerReceiver(receiver, intentFilter);
manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
{
public void onFailure(int paramAnonymousInt)
{
Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
}
public void onSuccess()
{
Log.d(TAG, "updateWfdEnableState");
}
});
sleep(1);
manager.setDialogListener(channel, this);
manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
{
@Override
public void onSuccess()
{
Log.d(TAG, "discoverPeers success");
}
@Override
public void onFailure(int reasonCode)
{
Log.d(TAG, "discoverPeers failed");
}
});
}
else
{
manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener()
{
@Override
public void onSuccess()
{
Log.d(TAG, "stopPeerDiscovery success");
}
@Override
public void onFailure(int reasonCode)
{
Log.d(TAG, "stopPeerDiscovery failed");
}
});
localWifiP2pWfdInfo.setWfdEnabled(false);
manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
{
public void onFailure(int paramAnonymousInt)
{
Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
}
public void onSuccess()
{
Log.d(TAG, "updateWfdEnableState");
}
});
sleep(4);
localWifiP2pWfdInfo.setWfdEnabled(true);
manager.setWFDInfo(channel, localWifiP2pWfdInfo, new WifiP2pManager.ActionListener()
{
public void onFailure(int paramAnonymousInt)
{
Log.d(TAG, "Failed to set WFD info with reason " + paramAnonymousInt + ".");
}
public void onSuccess()
{
Log.d(TAG, "updateWfdEnableState");
}
});
manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
{
@Override
public void onSuccess()
{
Log.d(TAG, "discoverPeers success");
}
@Override
public void onFailure(int reasonCode)
{
Log.d(TAG, "discoverPeers failed");
}
});
}
if (first)
startP2PDispeerTimeoutThread(40); // only start the thread 1 time...
}
在最初的日志记录中,我看到设备和手机连接成功。断开连接后,我在日志中看到设备丢失,之后,当我尝试连接时,我看到消息: I/wpa_supplicant(1839): [CTRL_IFACE]p2p0: P2P_CONNECT da:57:ef:cb:8e :be pbc go_intent=0
在这一切都停止之后,应用程序仍在运行,我可以从每 40 秒停止并重新启动发现的线程中每秒运行的日志行中看到这一点。
如果有人知道为什么会发生这种行为,请告诉我。现在恢复的唯一方法是重新启动电路板(但这不是一个选项)。
谢谢你的回复,阿维