[Android Software Development] Geeks Empire:
WiFi Direct | Android Beam [Client|Server][Data Transferring]

[IMG="wd"]https://xdaforums.com/attachment.php?attachmentid=4284718&stc=1&d=1506495920[/IMG]​

WiFi Direct can be used as main part of data transferring Or you can use it after initial connection with NFC. Android System uses Wifi Direct & Bluetooth to transfer a large amount of data after NFC connection.

### Let Start Coding ###
​

Note: Developing for Socket Communication needs vivid vision to understand how it works. Then use all components correctly step by step. So I will explain more about each section. Read Carefully.

. Wifi Direct | Client

Create a Project on Android Studio. Set minSdk to API 14 & Open AndroidManifest.xml to add required permissions and features

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

So create 3 classes & register them to Manifest.

ClientActivity

ClientReceiver

ClientService

Open ClientActivity. First, I need a file for sending over Wifi. You can use a file inside your app as assets, from SdCard Or create general FilePicker.

I set an image from /sdcard/Download/ directory. @onCreate(Bundle)

File [B][COLOR="Red"]fileToSend [/COLOR][/B]= new File(Environment.getExternalStorageDirectory().getPath() + "/Download/shuttle.jpg");

Now, You should initialize instance WifiP2pManager @onCreate(Bundle)

WifiP2pManager wifiManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
Channel wifichannel = wifiManager.initialize(this, getMainLooper(), null);

Then, You should Register a BroadcastReceiver with proper IntentFilter Actions.

IntentFilter wifiClientReceiverIntentFilter = new IntentFilter();
wifiClientReceiverIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
wifiClientReceiverIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
wifiClientReceiverIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
wifiClientReceiverIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
registerReceiver([B]ClientReceiver[/B]/*I will edit receiver later*/, wifiClientReceiverIntentFilter);

After this, You should invoke Peer Descovery. Also, It makes device discoverable

wifiManager.discoverPeers(wifichannel, new WifiP2pManager.ActionListener() {
public void onSuccess() {
//done
}
public void onFailure(int i) {
}});

And wait in ClientReceiver to setup peers. But, It is better to create a function in ClientActivity & pass instance of activity to receiver to access the functions. Check Sample Codes

public void [B][COLOR="red"]listOfPeers[/COLOR][/B](final WifiP2pDeviceList peers) {
ListView peerView = (ListView) findViewById(R.id.peers_listview);
ArrayList<String> peersStringArrayList = new ArrayList<String>();

for(WifiP2pDevice wd : peers.getDeviceList()) {
peersStringArrayList.add(wd.deviceName);
}

peerView.setClickable(true);
ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, peersStringArrayList.toArray());
peerView.setAdapter(arrayAdapter);

peerView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, int arg2,long arg3) {
TextView tv = (TextView) view;

WifiP2pDevice device = null;
for(WifiP2pDevice wd : peers.getDeviceList()) {
if(wd.deviceName.equals(tv.getText()))
device = wd;
}

[B][COLOR="red"]if(device != null) {
/*Connect to first Device*/
targetDevice = device;

WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
wifiManager.connect(wifichannel, config, new WifiP2pManager.ActionListener() {
public void onSuccess() {}
public void onFailure(int reason) {}
});
}[/COLOR][/B]
}});}

Open ClientReceiver to request list of peers when proper action occurs Check Sample Codes

if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
manager.requestPeers(channel, new WifiP2pManager.PeerListListener() {
public void onPeersAvailable(WifiP2pDeviceList peers) {
[COLOR="DarkOrchid"]activity[/COLOR].[B][COLOR="red"]listPeers[/COLOR][/B](peers);
}});
}

I set codes for connecting to a peer. But rewrite it here to consider it here in details

public void connectToPeer(final WifiP2pDevice wifiPeer){
targetDevice = wifiPeer;
/*[COLOR="Red"]Wi-Fi P2p configuration for setting up a connection[/COLOR]*/
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = wifiPeer.deviceAddress;
wifiManager.connect([COLOR="red"]wifichannel[/COLOR], [COLOR="red"]config[/COLOR], new WifiP2pManager.ActionListener() {
public void onSuccess() {}
public void onFailure(int reason) {}
}); }

Now, It is time to perform sending actions in ClientService and for this you should pass required info to service to open socket and write on it...

Port Number

WifiP2pInfo

File

So, After registering a receiver to get information when proper actions occur & getting list of peers, connection stablished & Now you can write data to Socket.OutputStream

Intent clientServiceIntent = new Intent(this, ClientService.class);
clientServiceIntent.putExtra("fileToSend", [B][COLOR="red"]fileToSend[/COLOR][/B]);
clientServiceIntent.putExtra("port", Integer.valueOf([B][COLOR="red"]port[/COLOR][/B]/*set what you want*/));
clientServiceIntent.putExtra("wifiInfo", [B][COLOR="Red"]wifiInfo[/COLOR][/B]);
startService(clientServiceIntent);

Then Open ClientService & set to get passed data

port = (Integer) intent.getExtras().get("port");
fileToSend = (File) intent.getExtras().get("fileToSend");
clientResult = (ResultReceiver) intent.getExtras().get("clientResult");
wifiInfo = (WifiP2pInfo) intent.getExtras().get("wifiInfo");

Now you can define socket and try to write data.

Before that you need proper address of target device

InetAddress [COLOR="RoyalBlue"]targetIP [/COLOR]= [B][COLOR="red"]wifiInfo[/COLOR][/B].groupOwnerAddress;

Now you can open socket and writing data Check Sample Codes

try {
Socket clientSocket = new Socket([B][COLOR="royalblue"]targetIP[/COLOR][/B], [B][COLOR="Red"]port[/COLOR][/B]);
OutputStream os = clientSocket.getOutputStream();
PrintWriter pw = new PrintWriter(os);

InputStream is = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);

byte[] buffer = new byte[4096];
FileInputStream fis = new FileInputStream(fileToSend);
BufferedInputStream bis = new BufferedInputStream(fis);

[B][COLOR="RoyalBlue"]while(true) {
int bytesRead = bis.read(buffer, 0, buffer.length);

if(bytesRead == -1) {break;}

[SIZE="4"]os.write(buffer,0, bytesRead);[/SIZE]
os.flush();
}[/COLOR][/B]
fis.close();
bis.close();
br.close();
isr.close();
is.close();
pw.close();
os.close();

clientSocket.close();
}
catch(Exception e) {e.printStackTrace();}

. Wifi Direct | Server

First, Register a BroadcastReceiver with Same IntentFilter Actions to get notification of connection information & specify a Path to store receiving data

/*this should be a directory*/
File downloadTarget = new File(Environment.getExternalStorageDirectory().getPath() + "/Download/");

Then start service and pass required data and prepare it to listen on socket with same port

Path to Store Data

Port Number

Intent serverServiceIntent = new Intent(this, ServerService.class);
serverServiceIntent.putExtra("saveLocation", downloadTarget);
serverServiceIntent.putExtra("port", Integer.valueOf(port));
startService(serverServiceIntent);

Now you can accept socket from specified port on server side and listen to read data Check Sample Codes

try {
[B][COLOR="royalblue"]ServerSocket welcomeSocket = new ServerSocket(port);
Socket socket = welcomeSocket.accept();[/COLOR][/B]

InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);

OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);

String inputData = "";
String savedAs = "WifiDirectDemo." + System.currentTimeMillis();
File file = new File(saveLocation, savedAs);

byte[] buffer = new byte[4096];
int bytesRead;
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);

/*[B][COLOR="Red"]Read data from Socket & Write it to a file[/COLOR][/B]*/
while(true)
{
bytesRead = is.read(buffer, 0, buffer.length);
if(bytesRead == -1){break;}
bos.write(buffer, 0, bytesRead);
bos.flush();
}
bos.close();
socket.close();
}
catch(Exception e) {e.printStackTrace();}

Download Source Code & Enjoy

Don't forget to Hit Thanks​