I have an Android app where I'd like to send data between 2 or more devices using Android's WiFi Direct P2P feature. My app is created based off Google's WiFi Direct Demo. The problem is, I wan to send data from the my server (group owner) to the client. The demo does not show how to do this. What I have tried is the following, but keep getting a "java.net.UnknownHostException: Host is unresolved" error.
What I currently do is:
In the WifiP2pManager.ConnectionInfoListener interface, I implement the onConnectionInfoAvailalbe like below:
public void onConnectionInfoAvailable(WifiP2pInfo info) {
if(mInitiatedConnection || mInitiatedDiscover) {
if (mPeerSelectionDialog != null && mPeerSelectionDialog.isShowing()) {
mPeerSelectionDialog.dismiss();
mPeerSelectionDialog = null;
}
if (info.groupFormed && info.isGroupOwner) {
Uri[] uris = getSelectedFiles();
//send data to clients
new ServerAsyncTask(getActivity(),info,uris).execute();
} else if (info.groupFormed) {
//Ping Server with IP address
new PingServerAsyncTask(getActivity(),info).execute();
//Wait for Server to Send data
new FileServerAsyncTask(getActivity(),mManager,mChannel).execute();
}
Below are my implementations for the three threads: FileServerAsyncTask (irrelevant code removed)
public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
/**
* @param context
*/
public FileServerAsyncTask(Context context, WifiP2pManager m, WifiP2pManager.Channel c) {
//intialize
}
@Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
Log.d(MultiImageSelectorFragment.TAG, "Server: Socket opened");
Socket client = serverSocket.accept();
Log.d(MultiImageSelectorFragment.TAG, "Server: connection done");
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ context.getPackageName() + "/wifip2pshared/" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
Log.d(MultiImageSelectorFragment.TAG, "server: copying files " + f.toString());
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
Log.e(MultiImageSelectorFragment.TAG, e.getMessage());
return null;
}
}
/*
* (non-Javadoc)
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(String result) {
//Do stuff with data..
}
ServerAsyncTask(empty code/initalizers removed as it's not relevant)
public static class ServerAsyncTask extends AsyncTask<Void, Void, String> {
public ServerAsyncTask(Context context, WifiP2pInfo info, Uri[] uris) {
}
@Override
protected String doInBackground(Void... params) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8988);
Log.d(MultiImageSelectorFragment.TAG, "Server: Socket opened");
boolean serverIsRunning = true;
while(serverIsRunning) {
Socket client = serverSocket.accept();
String addr = client.getInetAddress().toString();
sendPictures(addr);
}
serverSocket.close();
return null;
} catch (IOException e) {
Log.e(MultiImageSelectorFragment.TAG, e.getMessage());
return null;
}finally {
}
}
private void sendPictures(String remoteAddress) {
Uri uri = mURIs[0];
Log.d(MultiImageSelectorFragment.TAG, "Intent----------- ");
Intent serviceIntent = new Intent(context, FileTransferService.class);
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
//serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS, mInfo.groupOwnerAddress.getHostAddress());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS, remoteAddress);
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
context.startService(serviceIntent);
}
}
PingServerAsyncTask (empty code/initalizers removed as it's not relevant)
public static class PingServerAsyncTask extends AsyncTask<Void, Void, String> {
public PingServerAsyncTask(Context context, WifiP2pInfo m) {
}
@Override
protected String doInBackground(Void... params) {
String host = mInfo.groupOwnerAddress.getHostAddress();
Socket socket = new Socket();
int port = 8988;
int SOCKET_TIMEOUT = 5000;
try {
Log.d(MultiImageSelectorFragment.TAG, "Opening client socket - ");
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Toast.makeText(context, "server:"+host + "me:"+socket.getLocalAddress(), Toast.LENGTH_LONG).show();
Log.d(MultiImageSelectorFragment.TAG, "Client socket - " + socket.isConnected());
} catch (Exception e) {
Log.e(MultiImageSelectorFragment.TAG, e.getMessage());
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
return null;
}
}
The idea behind the code is: Group Owner (Server)
Not Group Owner (client)
The problem is that when the server tries to send the data in step marked (*), I get a java.net.UnknownHostException: Host is unresolved: exception. I can't figure out why I get that exception? The IP address I use is the one I just got from the client pinging the server, so it should be correct? Not sure what the issue is?
(Note: I didn't include FileTransferService.class implementation since it's an exact copy of the one from the Google WifiDirect demo so is available in the link from the first paragraph)
You should use the socket input and output streams to communicate between client and server.
After connection at server side:
dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
dataInputStream = new DataInputStream(clientSocket.getInputStream());
To send text message:
dataOutputStream.writeUTF(message);
dataOutputStream.flush();
I've answered similar question here: Peer to peer data sharing using Wi-Fi direct
Let me know if that didn't help. Goodluck.