Android Wi-Fi直連 傳輸數(shù)據(jù)
一旦兩個設(shè)備之間建立了Wi-Fi直連,那么這兩個設(shè)備之間就可以通過socket
傳輸數(shù)據(jù)大概得步驟如下:
- 通過
ServerSocket
創(chuàng)建一個server端,在后臺一直堅挺是否有client端連接 - 通過
Socket
建立一個client端昌抠,根據(jù)server端的ip和port,連接到server端 - 建立連接之后译蒂,通過client向server端發(fā)送數(shù)據(jù)
- server端接到數(shù)據(jù)之后,可以對數(shù)據(jù)做對應(yīng)的處理
Client
端的核心邏輯
-
在服務(wù)中創(chuàng)建一個
client
谊却,并發(fā)送數(shù)據(jù)public class FileTransferService extends IntentService{ ... @Override protected void onHandleIntent(Intent intent) { Context context = getApplicationContext(); if(intent.getAction().equals(ACTION_SEND_FILE)){ String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH); String host = intent.getExtras().getString(EXTRAS_GROUP_ADDRESS); Socket socket = new Socket(); int port = intent.getExtras().getInt(EXTRAS_GROUP_PORT); try{ socket.bind(null); //根據(jù)server端的地址和端口建立socket柔昼,并設(shè)置超時 socket.connect(new InetSocketAddress(host, port),SOCKET_TIMEOUT); OutputStream os = socket.getOutputStream(); ContentResolver cr = context.getContentResolver(); InputStream is = null; is = cr.openInputStream(Uri.parse(fileUri)); //發(fā)送數(shù)據(jù) DeviceDetailFragment.copyFile(is, os); }catch(Exception ex){ }finally{ if(socket != null){ if(socket.isConnected()){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } } } }
-
需要從相冊中選擇圖片,并啟動service
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
在
onActivityResult
中獲得選擇的圖像Uri uri = data.getData(); TextView statusText = (TextView)mContentView.findViewById(R.id.status_text); statusText.setText("Sending: "+uri); Intent i = new Intent(getActivity(), FileTransferService.class); i.setAction(FileTransferService.ACTION_SEND_FILE); i.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString()); i.putExtra(FileTransferService.EXTRAS_GROUP_ADDRESS, info.groupOwnerAddress.getHostAddress()); i.putExtra(FileTransferService.EXTRAS_GROUP_PORT, 8988); getActivity().startService(i);
Server
端核心代碼
在設(shè)備連接之后炎辨,server就通過ServerSocket
一直監(jiān)聽client端的連接捕透,一旦有client的請求,將client發(fā)來的數(shù)據(jù)
保存在本地,需要通過線程處理
public static class FileServerAsnycTask extends AsyncTask<Void,Void,String>{
private Context context;
private TextView statusText;
public FileServerAsnycTask(Context context,View statusText){
this.context = context;
this.statusText = (TextView)statusText;
}
@Override
protected String doInBackground(Void... params) {
try{
//創(chuàng)建socket監(jiān)聽
ServerSocket socket = new ServerSocket(8988);
Socket client = socket.accept();
//一旦有client端的連接碴萧,就接收client發(fā)來的數(shù)據(jù)并處理
final File f = new File(Environment.getExternalStorageDirectory()+"/"+
context.getPackageName()+"/wifishared-"+System.currentTimeMillis()+".jpg");
File dirs = new File(f.getParent());
if(!dirs.exists())
dirs.mkdirs();
f.createNewFile();
InputStream is = client.getInputStream();
copyFile(is, new FileOutputStream(f));
socket.close();
return f.getAbsolutePath();
}catch(Exception e){
return null;
}
}
//接受完成之后乙嘀,可以通過相冊打開查看
@Override
protected void onPostExecute(String result) {
if(result != null){
statusText.setText("File copied - "+result);
Intent i = new Intent();
i.setAction(Intent.ACTION_VIEW);
i.setDataAndType(Uri.parse("file//"+result), "image/*");
context.startActivity(i);
}
}
}
完整的代碼請查看
測試可以在兩個手機(jī)同時安裝這個程序,一個手機(jī)是client端勿决,一個手機(jī)是server端乒躺,連接之后招盲,就可以相互傳數(shù)據(jù)
完整的代碼