WFD onGroupInfoAvailable is called with NULL WifiP2pGroup - android

I tried creating the WifiDirect group using the call createGroup(). After creation of the group the onFailure call back is getting called and onGroupInfoAvailable is called and I cloud get the group owner MACadress. But whenever the onSuccess gets called and onGroupInfoAvailable is called
with the null WifiP2pGroup.
mWifiP2PManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mWifiP2PManager.initialize(this, getMainLooper(), null);
deletePersistentGroups();
mWifiP2PManager.requestGroupInfo(mChannel, new WifiP2pManager.GroupInfoListener() {
#Override
public void onGroupInfoAvailable(WifiP2pGroup wifiP2pGroup) {
if(wifiP2pGroup.getOwner().deviceAddress!=null){
DeviceP2PMAC = wifiP2pGroup.getOwner().deviceAddress;
startbleadvertise();
}
}
});
mWifiP2PManager.createGroup(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(getBaseContext(),"Group created",Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(int reason) {
Toast.makeText(getBaseContext(),"Group creation failed",Toast.LENGTH_LONG).show();
}
});

Related

WifiP2pManager createGroup and removeGroup are failing with BUSY state

On both of my devices when I try to use WifiP2pManager's createGroup or removeGroup I get the onFailure callback with 2 (BUSY) as reason.
I've tried to use suggestion given here WifiP2pManager return BUSY state on CreateGroup (removing group before creating a new one), but it didn't help because I'm always getting onFailure
callback in removeGroup.
Devices I tested on: LG Optimus G (CM 12.1 - Android 5.1), Gigabyte GSmart Guru G1 (stock Android 4.2).
UPDATE
The code is:
manager.removeGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Debug.d();
manager.createGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Debug.d();
}
#Override
public void onFailure(int reason) {
Debug.d("" + reason);
}
});
}
#Override
public void onFailure(int reason) {
Debug.d("" + reason);
}
});
I was getting this error because I tried to use removeGroup when group didn't exist. The solution is to check whether the current group exist before removing it or creating a new one.
Here's the working code (I use Retrolambda):
manager.requestGroupInfo(channel, group -> {
if (group != null) {
Debug.d("group != null");
manager.removeGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Debug.d();
manager.createGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Debug.d();
}
#Override
public void onFailure(int reason) {
Debug.d("" + reason);
}
});
}
#Override
public void onFailure(int reason) {
Debug.d("" + reason);
}
});
} else {
manager.createGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Debug.d();
}
#Override
public void onFailure(int reason) {
Debug.d("" + reason);
}
});
}
});
As #Dr.Jukka commented: Having the wifi turned off, can also cause a BUSY state. That was at least in my case.

How to create multiple accounts with the oneDrive SDK for Android?

I use the oneDrive sdk for Android:
https://github.com/OneDrive/onedrive-sdk-android
I have no problem to create an account.
Here is the code I use:
final DefaultCallback<IOneDriveClient> callback = new DefaultCallback<IOneDriveClient>(getActivity()) {
#Override
public void success(final IOneDriveClient result) {
mOneDriveClient = result;
mOneDriveClient
.getDrive()
.buildRequest()
.get(new ICallback<com.onedrive.sdk.extensions.Drive>() {
#Override
public void success(final com.onedrive.sdk.extensions.Drive onedrive) {
new Thread(new Runnable() {
#Override
public void run() {
//In this method I retrieve the account infos:
//DriveId, quotas, displayName ....
createOneDriveAccount(onedrive);
}
}).start();
}
#Override
public void failure(ClientException ex) {
Toast.makeText(getActivity(),"pas bon", Toast.LENGTH_SHORT)
.show();
}
});
}
#Override
public void failure(final ClientException error) {
}
};
new OneDriveClient
.Builder()
.fromConfig(createConfig())
.loginAndBuildClient(getActivity(), callback);
But I can not renew the operation to create and register another account. How can I access the login page again?
Thank you for picking me up.

receiving error when building an android project with Neura

I'm working with neura sdk in order to detect current data of a user(where he/she is, where were they 10 min ago etc).
I want to login to their api, and authenticate my user, however - when i call NeuraApiClient.authenticate(...) nothing happens.
I followed neura documentations, but still - nothing happens.
Here's my code :
public class MainActivity extends AppCompatActivity {
private ArrayList<Permission> mPermissions;
private AuthenticationRequest mAuthenticateRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Builder builder = new Builder(this);
NeuraApiClient neuraApiClient = builder.build();
neuraApiClient.setAppUid(getResources().getString(R.string.app_uid));
neuraApiClient.setAppSecret(getResources().getString(R.string.app_secret));
neuraApiClient.connect();
fetchPermissions(neuraApiClient);
neuraApiClient.authenticate(100, mAuthenticateRequest);
}
private void fetchPermissions(final NeuraApiClient client) {
client.getAppPermissions(new GetPermissionsRequestCallbacks() {
#Override
public void onSuccess(final List<Permission> permissions) throws RemoteException {
runOnUiThread(new Runnable() {
#Override
public void run() {
mPermissions = new ArrayList<>(permissions);
mAuthenticateRequest = new AuthenticationRequest();
mAuthenticateRequest.setAppId(client.getAppUid());
mAuthenticateRequest.setAppSecret(client.getAppSecret());
mAuthenticateRequest.setPermissions(mPermissions);
}
});
}
#Override
public void onFailure(Bundle resultData, int errorCode) throws RemoteException {
}
#Override
public IBinder asBinder() {
return null;
}
});
}
}
getAppPermissions is an asynchronous call, and the data is fetched on GetPermissionsRequestCallbacks.
in GetPermissionsRequestCallbacks you're initiating mAuthenticateRequest which is in use of authenticate method.
Which means you have to wait untill onSuccess of GetPermissionsRequestCallbacks is called, and only then you can call
neuraApiClient.authenticate(100, mAuthenticateRequest);
Basically, if you don't wait for mAuthenticateRequest to be fetched, you authenticate with mAuthenticateRequest = null, and neuraApiClient.authenticate(..) fails.
You can do something like this : call authenticate when the results are received -
private void fetchPermissions(final NeuraApiClient client) {
client.getAppPermissions(new GetPermissionsRequestCallbacks() {
#Override
public void onSuccess(final List<Permission> permissions) throws RemoteException {
runOnUiThread(new Runnable() {
#Override
public void run() {
mPermissions = new ArrayList<>(permissions);
mAuthenticateRequest = new AuthenticationRequest();
mAuthenticateRequest.setAppId(client.getAppUid());
mAuthenticateRequest.setAppSecret(client.getAppSecret());
mAuthenticateRequest.setPermissions(mPermissions);
client.authenticate(100, mAuthenticateRequest);
}
});
}
...
});
}

Android WiFi-Direct: discovering, connecting issues. Detailed discussion

I'm developing an application, which uses wifi-direct to create groups of maximum 4 devices ( 1 host + 3 peers). I read manuals of wifi-direct from developer.android.com, found this wonderful answer: https://stackoverflow.com/a/31641302/3106249 - and still, I have couple of issues which I don't know how to handle.
First problem step by step:
Registering local service and creating group on host device.
Map<String, String> record = new HashMap<String, String>();
record.put(TXTRECORD_PROP_AVAILABLE, "visible");
record.put(Core.SESSION_KEY, Core.SESSION_KEY_VALUE);
record.put(Core.SERVICE_INSTANCE_KEY, SERVICE_INSTANCE);
localService = WifiP2pDnsSdServiceInfo.newInstance(SERVICE_INSTANCE, Core.SERVICE_REG_TYPE, record);
manager.clearLocalServices(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "clearLocalServices success");
manager.addLocalService(channel, localService, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "addLocalService success");
manager.createGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "createGroup success");
}
#Override
public void onFailure(int reason) {
Log.d(TAG, "createGroup fail: " + reason);
}
});
}
#Override
public void onFailure(int reason) {
Log.d(TAG, "addLocalService fail: " + reason);
}
});
}
#Override
public void onFailure(int reason) {
Log.d(TAG, "clearLocalServices fail: " + reason);
}
});
Discovering required peed by host device with 10 seconds interval.
manager.removeServiceRequest(channel, serviceRequest, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "discovering, removeServiceRequest success");
manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "discovering, stopPeerDiscovery success");
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "discovering, discoverPeers success");
manager.addServiceRequest(channel, serviceRequest, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "discovering, addServiceRequest success");
manager.discoverServices(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
//Log.d(TAG, "discoverServices success");
}
#Override
public void onFailure(int reason) {
Log.d(TAG, "discoverServices fail: " + reason);
}
});
}
#Override
public void onFailure(int reason) {
Log.d(TAG, "addServiceRequest fail: " + reason);
}
});
}
#Override
public void onFailure(int reason) {
Log.d(TAG, "discoverPeers fail: " + reason);
}
});
}
#Override
public void onFailure(int reason) {
Log.d(TAG, "stopPeerDiscovery fail: " + reason);
}
});
}
#Override
public void onFailure(int reason) {
Log.d(TAG, "clearServiceRequests fail: " + reason);
}
});
Sending connection invite (by calling WiFiP2pManager#connect())
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
manager.connect(channel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "manger.onSuccess with " + device.deviceName);
}
#Override
public void onFailure(int errorCode) {
Log.d(TAG, "Failed connecting to service " + errorCode);
}
});
Connection prompt dialog appears on peer. Accepting connection.
Connection prompt dialog NEVER appears on host device.
Second problem is, that when I call WiFiP2pManager#connect(), it returns in ActionListenter's onFailure method, with error code 2. Then, I call connect again after 5-10 seconds, and it returns in onSuccess method. Despite this, on connected device does not appear connection prompt dialog, which means that no connection invite is received I suppose.
These two issues are the main problems that makes application totally unusable.
Can anybody explain to me what I'm doing wrong or how to handle these issues?
UPD
Attaching logs for small discovery session.
Host log (nexus 7): http://pastebin.com/ycfqRE4m
Peer log (nexus 10): http://pastebin.com/5kbp6e7A

How do i get a Peer-to-peer WiFi service discovery to work?

I'm trying to build a server-client architecture using two Android devices with a peer-to-peer WiFi connection. I've got a clear distinction between client and server, so I'm trying to prune out unnecessary code. Using directions from http://developer.android.com/training/connect-devices-wirelessly/nsd-wifi-direct.html I've got...
PeerToPeerService
public class PeerToPeerService {
private static final Logger LOG = LoggerFactory.getLogger(PeerToPeerService.class);
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private final Context mContext;
private final WifiP2pDnsSdServiceInfo mService;
public PeerToPeerService(Context context, String name) {
mContext = context;
Map<String, String> record = new HashMap<String, String>();
record.put(Constants.SERVICE_PROPERTY_NAME, name);
record.put(Constants.SERVICE_PROPERTY_PORT, "12345");
mService = WifiP2pDnsSdServiceInfo.newInstance(
"_test", "_presence._tcp", record);
}
public void start() {
mManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null);
mManager.addLocalService(mChannel, mService, new ActionListener() {
#Override
public void onSuccess() {
LOG.info("Started Service");
}
#Override
public void onFailure(int error) {
LOG.warn("Failed to Start Service: {}", error);
}
});
}
public void stop() {
mManager.removeLocalService(mChannel, mService, null);
mManager = null;
LOG.info("Stopped Service");
}
}
PeerToPeerClient
public class PeerToPeerClient {
private static final Logger LOG = LoggerFactory.getLogger(PeerToPeerClient.class);
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private final Context mContext;
public PeerToPeerClient(Context context) {
mContext = context;
}
public void findServices() {
mManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null);
mManager.setDnsSdResponseListeners(mChannel,
new DnsSdServiceResponseListener() {
#Override
public void onDnsSdServiceAvailable(String instanceName,
String registrationType, WifiP2pDevice device) {
LOG.info("A");
LOG.info("Service Found: {}:{}", instanceName, registrationType);
}
},
new DnsSdTxtRecordListener() {
#Override
public void onDnsSdTxtRecordAvailable(String fullDomainName, Map<String, String> record,
WifiP2pDevice device) {
LOG.info("B");
LOG.info("{}:{} is {}", device.deviceName,
record.get(Constants.SERVICE_PROPERTY_PORT), record.get(Constants.SERVICE_PROPERTY_NAME));
}
});
WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
mManager.addServiceRequest(mChannel, serviceRequest,
new ActionListener() {
#Override
public void onSuccess() {
LOG.info("Added service discovery request");
}
#Override
public void onFailure(int error) {
LOG.info("Failed adding service discovery request: {}", error);
}
});
mManager.discoverServices(mChannel, new ActionListener() {
#Override
public void onSuccess() {
LOG.info("Service discovery initiated");
}
#Override
public void onFailure(int arg0) {
LOG.info("Service discovery failed");
}
});
}
}
Every single ActionListener has onSuccess called, no failures anywhere. But I never get any of the setDnsSdResponseListeners callbacks. Any ideas where I might have gone wrong?
I have some experience with working with Wi-Fi Direct on Android devices, I am writing an app to connect devices ad-hoc and enabling chatting across this link.
To be discoverable on Wi-Fi Direct, both devices needs to be scanning, ie. mWifiP2pManager.discoverPeers().
Strangely, this also affects the discovery of DnsTxtRecordServices. Thus, I have found it works if you start your scanning( discoverPeers()) on both devices and then start discoverPeers().
Hope this helps! :)
I think you have missed some points :
PeerToPeerService : server code
1. implement discovery of clients
PeerToPeerClient : client code
1. implement addint client local service
which will be discovered by servers
PeerToPeerService :
// after adding local service
manager.setDnsSdResponseListeners(channel,
new DnsSdServiceResponseListener() {
...
}
PeerToPeerClient :
mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null);
// add client local service
mManager.addLocalService(mChannel, mService, new ActionListener() {
#Override
public void onSuccess() {
LOG.info("Started Service");
}
#Override
public void onFailure(int error) {
LOG.warn("Failed to Start Service: {}", error);
}
});
After this code, you will be able to get callback onDnsSdResponseListener and you can connect
After connect, you can check if you are server side or client side by WifiP2pInfo.isGroupOwner -- true for server and false for client
For both client & server, you must call addLocalService and discoverServices for WifiP2p to work.
Map record = new HashMap();
record.put("name","your_app_anme");
WifiP2pDnsSdServiceInfo serviceInfo = WifiP2pDnsSdServiceInfo.newInstance("_test", "_presence.tcp", record);
wifiP2pManager.addLocalService(wifiP2pChannel, serviceInfo, null);
wifiP2pManager.setDnsSdResponseListeners(wifiP2pChannel, new WifiP2pManager.DnsSdServiceResponseListener() {
#Override
public void onDnsSdServiceAvailable(String s, String s1, WifiP2pDevice wifiP2pDevice) {
Log.wtf("WTF", "device "+wifiP2pDevice.deviceName + "/"+wifiP2pDevice.deviceAddress);
}
}, new WifiP2pManager.DnsSdTxtRecordListener() {
#Override
public void onDnsSdTxtRecordAvailable(String s, Map<String, String> map, WifiP2pDevice wifiP2pDevice) {
Log.wtf("WTF", "got txt "+map.get("name") );
}
});
WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
wifiP2pManager.addServiceRequest(wifiP2pChannel, serviceRequest, null);
wifiP2pManager.discoverServices(wifiP2pChannel, null);
After tons of trying, I got the robust workable flow like this:
...
wifiP2pManager.clearLocalServices(wifiP2pChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
HashMap<String, String> record = new HashMap<>();
record.put("name", "Amos");
WifiP2pDnsSdServiceInfo serviceInfo = WifiP2pDnsSdServiceInfo.newInstance(AppConfig.DNS_SD_SERVICE_NAME, AppConfig.DNS_SD_SERVICE_TYPE, record);
wifiP2pManager.addLocalService(wifiP2pChannel, serviceInfo, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
wifiP2pManager.setDnsSdResponseListeners(wifiP2pChannel, WifiDirectFragment.this, WifiDirectFragment.this);
wifiP2pManager.clearServiceRequests(wifiP2pChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
wifiP2pManager.addServiceRequest(wifiP2pChannel, WifiP2pDnsSdServiceRequest.newInstance(), new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
wifiP2pManager.discoverPeers(wifiP2pChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
wifiP2pManager.discoverServices(wifiP2pChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// this is my recursive discovery approach
handler.postDelayed(discoveryRunnable, AppConfig.DNS_SD_SERVICE_DISCOVERABLE_DURATION_S * 1000);
}
#Override
public void onFailure(int code) {
}
});
}
#Override
public void onFailure(int code) {
}
});
}
#Override
public void onFailure(int code) {
}
});
}
#Override
public void onFailure(int code) {
}
});
}
#Override
public void onFailure(int code) {
}
});
}
#Override
public void onFailure(int code) {
}
});

Resources