问题
Yo,
I'm trying to get an Android device (it's a Nexus 7 although I can't imagine that matters too much) to communicate with a Raspberry Pi throught the wonders of WiFi Direct. Supposedly it's possible, and it seemed six hours ago like a better solution than going down the server-client route, but I'm running into issues
The Android developer website is nice in that it has two guides:
http://developer.android.com/training/connect-devices-wirelessly/wifi-direct.html http://developer.android.com/guide/topics/connectivity/wifip2p.html
Which is lovely, because I don't have masses of experience in Java. But the problem with... well quite a lot on that site actually, is that elements in code they deem straightfoward (i.e. where to put things) are often missing.
I've followed both guides pretty closely but I've reached a problem - the WIFI_P2P_PEERS_CHANGED_ACTION intent is never broadcast, so when I'm looking for peers, it starts the search, says everything is fine, but doesn't give me a list of the results... which I'm guessing it should
I've been wrestling with this for most of the day with a nice case of hayfever to make life that extra bit sweeter
CODE:
Activity:
package com.example.bingotest;
import java.util.ArrayList;
import java.util.List;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Build;
import android.os.Bundle;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.util.Log;
import android.view.Menu;
public class BingoActivity extends Activity {
private BingoView _view;
private IntentFilter _intentFilter = new IntentFilter();
private BroadcastReceiver _broadcastReceiver = null;
private WifiP2pManager _manager;
private Channel _channel;
private List _peers = new ArrayList();
private PeerListListener _peerListListener;
//-------------------------------------------------------------------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
_view = new BingoView(this);
setContentView(_view);
_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(this, getMainLooper(), null);
//_broadcastReceiver = new WiFiDirectBroadcastReceiver(_manager, _channel, this);
//registerReceiver(_broadcastReceiver, _intentFilter);
_peerListListener = new PeerListListener() {
@Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
Log.d("wifi", "here");
// Out with the old, in with the new.
_peers.clear();
_peers.addAll(peerList.getDeviceList());
if (_peers.size() == 0) {
Log.d("wifi", "No devices found");
return;
}
}
};
}
//-------------------------------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.bingo, menu);
return true;
}
//-------------------------------------------------------------------------------
@Override
public void onResume() {
super.onResume();
_broadcastReceiver = new WiFiDirectBroadcastReceiver(_manager, _channel, this, _peerListListener);
registerReceiver(_broadcastReceiver, _intentFilter);
}
//-------------------------------------------------------------------------------
@Override
public void onPause() {
super.onPause();
unregisterReceiver(_broadcastReceiver);
}
}
WiFiDirectBroadcastReceiver Class:
package com.example.bingotest;
import java.util.ArrayList;
import java.util.List;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.util.Log;
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager _manager;
private Channel _channel;
private BingoActivity _activityRef;
private List _peers = new ArrayList();
PeerListListener _peerListListener;
//-------------------------------------------------------------------------------
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel, BingoActivity activity, PeerListListener peerListListener) {
super();
_manager = manager;
_channel = channel;
_activityRef = activity;
_peerListListener = peerListListener;
_manager.discoverPeers(_channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Log.d("wifi", "onsuccess");
}
@Override
public void onFailure(int reasonCode) {
Log.d("wifi", "onfailure");
}
});
}
//-------------------------------------------------------------------------------
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("wifi", "receive: " + intent.getAction());
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// Check to see if Wi-Fi is enabled and notify appropriate activity
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
Log.d("wifi", "WIFI DIRECT ON");
} else {
Log.d("wifi", "WIFI DIRECT OFF");
}
}
else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
Log.d("wifi", "Peers changed");
if (_manager != null) {
_manager.requestPeers(_channel, _peerListListener);
}
}
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
// Respond to new connection or disconnections
}
else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// Respond to this device's wifi state changing
}
}
//-------------------------------------------------------------------------------
}
(apologies for potentially messy and wasteful code - I've been experimenting trying to get results)
Help would be much obliged. My guess is peerListListener is in the wrong place. My Android knowledge is pretty minimal.
Thanks in advance.
回答1:
I can see you did an initial discovery when constructing you WiFiDirectBroadcastReceiver
and then in your Activity.onResume() you first construct WiFiDirectBroadcastReceiver and then registerReceiver().
@Override
public void onResume() {
super.onResume();
_broadcastReceiver = new WiFiDirectBroadcastReceiver(_manager, _channel, this, _peerListListener);
registerReceiver(_broadcastReceiver, _intentFilter);
}
The problem that you do not see the response come back is probably because of the sequence.Try move discoverPeers() to Activity.onResume() should solve the problem.
回答2:
You're missing a call to DiscoverPeers:
To start searching for nearby devices with Wi-Fi Direct, call discoverPeers().
The specific app logic for when you want that initial discovery to happen will determine where in your code that happens. In the API samples for SDK 17, this happens when an option item is clicked from the menu. This could easily be moved to the onResume method (this will be initiated every time the activity is resumed, or in the click listener for a button on the screen.
For future troubleshooting, I would recommend keeping the WiFiDirectBroadcastReceiver class inside the Activity's class (unless you need to reuse the code) for ease of use with callbacks -- you can access the outer class's methods directly from the inner class and make this a bit easier to troubleshoot.
回答3:
Try changing this:
_manager.requestPeers(_channel, _peerListListener);
to this:
_manager.requestPeers(_channel, _activityRef._peerListListener);
回答4:
Google is providing a Wifi Direct example since Oct 2011: https://android.googlesource.com/platform/development/+/master/samples/WiFiDirectDemo
I added this link because it took me a while to find it (original link is reffering to Wifi P2P Demo, not WiFiDirectDemo).
来源:https://stackoverflow.com/questions/17530885/android-java-wifi-direct-peer-list