Wi-Fi Direct (P2P) به دستگاه هایی با سخت افزار مناسب اجازه می دهد تا مستقیماً از طریق Wi-Fi بدون نقطه دسترسی میانی به یکدیگر متصل شوند. با استفاده از این APIها، هنگامی که هر دستگاه از Wi-Fi P2P پشتیبانی می کند، می توانید دستگاه های دیگر را کشف کرده و به آنها متصل شوید، سپس از طریق یک اتصال سریع در فواصل بسیار طولانی تر از اتصال بلوتوث ارتباط برقرار کنید. این برای برنامه هایی مفید است که داده ها را بین کاربران به اشتراک می گذارند، مانند یک بازی چند نفره یا یک برنامه اشتراک گذاری عکس.
API های Wi-Fi P2P از بخش های اصلی زیر تشکیل شده اند:
- روشهایی که به شما امکان میدهند کشف، درخواست و اتصال به همتایان را که در کلاس
WifiP2pManager
تعریف شدهاند، انجام دهید. - شنوندگانی که به شما امکان می دهند از موفقیت یا شکست تماس های روش
WifiP2pManager
مطلع شوید. هنگام فراخوانی متدهایWifiP2pManager
، هر متد می تواند شنونده خاصی را به عنوان پارامتر دریافت کند. - اهدافی که شما را از رویدادهای خاصی که توسط چارچوب Wi-Fi P2P شناسایی شده است، مانند اتصال قطع شده یا همتای تازه کشف شده، مطلع می کند.
شما اغلب از این سه جزء اصلی APIها با هم استفاده خواهید کرد. به عنوان مثال، میتوانید یک WifiP2pManager.ActionListener
را برای فراخوانی برای discoverPeers()
ارائه دهید تا متدهای ActionListener.onSuccess()
و ActionListener.onFailure()
بتوانند به شما اطلاع دهند. یک هدف WIFI_P2P_PEERS_CHANGED_ACTION
نیز پخش می شود اگر متد discoverPeers()
متوجه شود که لیست همتاها تغییر کرده است.
نمای کلی API
کلاس WifiP2pManager
روشهایی را ارائه میکند که به شما امکان میدهد با سختافزار Wi-Fi دستگاهتان تعامل داشته باشید تا کارهایی مانند کشف و اتصال به همتایان را انجام دهید. اقدامات زیر در دسترس است:
جدول 1. روش های Wi-Fi P2P
روش | توضیحات |
initialize() | برنامه را با چارچوب Wi-Fi ثبت می کند. قبل از تماس با هر روش دیگر Wi-Fi P2P با این تماس بگیرید. |
connect() | اتصال همتا به همتا را با دستگاهی با پیکربندی مشخص شده شروع می کند. |
cancelConnect() | هرگونه مذاکره گروهی همتا به همتا را لغو می کند. |
requestConnectInfo() | اطلاعات اتصال دستگاه را درخواست می کند. |
createGroup() | یک گروه همتا به همتا با دستگاه فعلی به عنوان مالک گروه ایجاد می کند. |
removeGroup() | گروه همتا به همتا کنونی را حذف می کند. |
requestGroupInfo() | اطلاعات گروه همتا به همتا را درخواست می کند. |
discoverPeers() | کشف همتایان را آغاز می کند. |
requestPeers() | لیست فعلی همتایان کشف شده را درخواست می کند. |
روشهای WifiP2pManager
به شما امکان میدهند از یک شنونده عبور کنید، به طوری که چارچوب Wi-Fi P2P میتواند فعالیت شما را از وضعیت تماس مطلع کند. رابط های شنونده موجود و فراخوانی های متد WifiP2pManager
مربوطه که از شنوندگان استفاده می کنند در جدول 2 توضیح داده شده است.
جدول 2. شنوندگان Wi-Fi P2P
رابط شنونده | اقدامات مرتبط |
WifiP2pManager.ActionListener | connect() ، cancelConnect() ، createGroup() ، removeGroup() و discoverPeers() |
WifiP2pManager.ChannelListener | initialize() |
WifiP2pManager.ConnectionInfoListener | requestConnectInfo() |
WifiP2pManager.GroupInfoListener | requestGroupInfo() |
WifiP2pManager.PeerListListener | requestPeers() |
APIهای Wi-Fi P2P مقاصدی را تعریف میکنند که وقتی رویدادهای P2P Wi-Fi خاصی اتفاق میافتد، مانند زمانی که همتای جدیدی کشف میشود یا زمانی که وضعیت Wi-Fi دستگاه تغییر میکند، پخش میشوند. می توانید با ایجاد یک گیرنده پخش که این اهداف را مدیریت می کند، برای دریافت این اهداف در برنامه خود ثبت نام کنید:
جدول 3. مقاصد Wi-Fi P2P
قصد | توضیحات |
WIFI_P2P_CONNECTION_CHANGED_ACTION | هنگامی که وضعیت اتصال Wi-Fi دستگاه تغییر می کند، پخش شود. |
WIFI_P2P_PEERS_CHANGED_ACTION | هنگامی که با discoverPeers() تماس میگیرید، پخش شود. اگر این هدف را در برنامه خود مدیریت کنید، معمولاً requestPeers() را برای دریافت لیستی از همتایان به روز می کنید. |
WIFI_P2P_STATE_CHANGED_ACTION | هنگامی که Wi-Fi P2P در دستگاه فعال یا غیرفعال است، پخش شود. |
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION | هنگامی که جزئیات دستگاه مانند نام دستگاه تغییر کرده است، پخش شود. |
یک گیرنده پخش برای مقاصد Wi-Fi P2P ایجاد کنید
یک گیرنده پخش به شما امکان می دهد اهداف پخش شده توسط سیستم اندروید را دریافت کنید تا برنامه شما بتواند به رویدادهایی که به آنها علاقه دارید پاسخ دهد. مراحل اساسی برای ایجاد یک گیرنده پخش برای مدیریت اهداف Wi-Fi P2P به شرح زیر است:
کلاسی ایجاد کنید که کلاس
BroadcastReceiver
را گسترش دهد. برای سازنده کلاس، از پارامترهایWifiP2pManager
،WifiP2pManager.Channel
و فعالیتی که این گیرنده پخش در آن ثبت می شود استفاده خواهید کرد. این به گیرنده پخش اجازه می دهد تا به روز رسانی ها را برای فعالیت ارسال کند و همچنین به Wi- دسترسی داشته باشد. سخت افزار Fi و کانال ارتباطی در صورت نیاز.در گیرنده پخش، اهداف مورد نظر خود را در متد
onReceive()
بررسی کنید. هر گونه اقدام لازم را بسته به قصد دریافت شده انجام دهید. به عنوان مثال، اگر گیرنده پخش یک هدفWIFI_P2P_PEERS_CHANGED_ACTION
دریافت می کند، می توانید متدrequestPeers()
را فراخوانی کنید تا لیستی از همتاهای کشف شده فعلی را دریافت کنید.
کد زیر نحوه ایجاد یک گیرنده پخش معمولی را به شما نشان می دهد. گیرنده پخش یک شی WifiP2pManager
و یک اکتیویتی را به عنوان آرگومان می گیرد و از این دو کلاس برای اجرای مناسب اقدامات مورد نیاز هنگامی که گیرنده پخش یک هدف دریافت می کند استفاده می کند:
کاتلین
/** * A BroadcastReceiver that notifies of important Wi-Fi p2p events. */ class WiFiDirectBroadcastReceiver( private val manager: WifiP2pManager, private val channel: WifiP2pManager.Channel, private val activity: MyWifiActivity ) : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val action: String = intent.action when (action) { WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION -> { // Check to see if Wi-Fi is enabled and notify appropriate activity } WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> { // Call WifiP2pManager.requestPeers() to get a list of current peers } WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION -> { // Respond to new connection or disconnections } WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION -> { // Respond to this device's wifi state changing } } } }
جاوا
/** * A BroadcastReceiver that notifies of important Wi-Fi p2p events. */ public class WiFiDirectBroadcastReceiver extends BroadcastReceiver { private WifiP2pManager manager; private Channel channel; private MyWiFiActivity activity; public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel, MyWifiActivity activity) { super(); this.manager = manager; this.channel = channel; this.activity = activity; } @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { // Check to see if Wi-Fi is enabled and notify appropriate activity } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // Call WifiP2pManager.requestPeers() to get a list of current peers } 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 } } }
در دستگاههای دارای Android 10 و بالاتر، اهداف پخش زیر غیرچسب هستند:
-
WIFI_P2P_CONNECTION_CHANGED_ACTION
- برنامه ها می توانند از
requestConnectionInfo()
،requestNetworkInfo()
، یاrequestGroupInfo()
برای بازیابی اطلاعات اتصال فعلی استفاده کنند. -
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
- برنامه ها می توانند از
requestDeviceInfo()
برای بازیابی اطلاعات اتصال فعلی استفاده کنند.
یک برنامه Wi-Fi P2P ایجاد کنید
ایجاد یک برنامه Wi-Fi P2P شامل ایجاد و ثبت یک گیرنده پخش برای برنامه شما، کشف همتایان، اتصال به همتا و انتقال داده به همتا است. بخش های زیر نحوه انجام این کار را توضیح می دهند.
راه اندازی اولیه
قبل از استفاده از API های Wi-Fi P2P، باید مطمئن شوید که برنامه شما می تواند به سخت افزار دسترسی داشته باشد و دستگاه از پروتکل Wi-Fi P2P پشتیبانی می کند. اگر Wi-Fi P2P پشتیبانی می شود، می توانید نمونه ای از WifiP2pManager
را دریافت کنید، گیرنده پخش خود را ایجاد و ثبت کنید و شروع به استفاده از API های Wi-Fi P2P کنید.
درخواست مجوز برای استفاده از سخت افزار Wi-Fi در دستگاه و اعلام کنید که برنامه شما دارای حداقل نسخه SDK صحیح در مانیفست Android است:
<uses-sdk android:minSdkVersion="14" /> <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" /> <!-- If your app targets Android 13 (API level 33) or higher, you must declare the NEARBY_WIFI_DEVICES permission. --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" <!-- If your app derives location information from Wi-Fi APIs, don't include the "usesPermissionFlags" attribute. --> android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" <!-- If any feature in your app relies on precise location information, don't include the "maxSdkVersion" attribute. --> android:maxSdkVersion="32" />
علاوه بر مجوزهای قبلی، APIهای زیر نیز نیاز به فعال کردن موقعیت مکانی دارند:
بررسی کنید که آیا Wi-Fi P2P روشن و پشتیبانی میشود یا خیر. هنگامی که هدف
WIFI_P2P_STATE_CHANGED_ACTION
را دریافت می کند، یک مکان خوب برای بررسی این موضوع در گیرنده پخش شما است. فعالیت خود را از وضعیت Wi-Fi P2P مطلع کنید و مطابق با آن واکنش نشان دهید:کاتلین
override fun onReceive(context: Context, intent: Intent) { ... val action: String = intent.action when (action) { WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION -> { val state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1) when (state) { WifiP2pManager.WIFI_P2P_STATE_ENABLED -> { // Wifi P2P is enabled } else -> { // Wi-Fi P2P is not enabled } } } } ... }
جاوا
@Override public void onReceive(Context context, Intent intent) { ... String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1); if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { // Wifi P2P is enabled } else { // Wi-Fi P2P is not enabled } } ... }
در متد
onCreate()
فعالیت خود، نمونه ای ازWifiP2pManager
را به دست آورید و با فراخوانیinitialize()
برنامه خود را با چارچوب Wi-Fi P2P ثبت کنید. این روش یکWifiP2pManager.Channel
را برمی گرداند که برای اتصال برنامه شما به چارچوب Wi-Fi P2P استفاده می شود. همچنین باید یک نمونه از گیرنده پخش خود را با اشیاءWifiP2pManager
وWifiP2pManager.Channel
همراه با اشاره به فعالیت خود ایجاد کنید. این به گیرنده پخش شما امکان می دهد تا فعالیت شما را از رویدادهای جالب مطلع کند و آن را متناسب با آن به روز کند. همچنین به شما امکان می دهد در صورت لزوم وضعیت Wi-Fi دستگاه را دستکاری کنید:کاتلین
val manager: WifiP2pManager? by lazy(LazyThreadSafetyMode.NONE) { getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager? } var channel: WifiP2pManager.Channel? = null var receiver: BroadcastReceiver? = null override fun onCreate(savedInstanceState: Bundle?) { ... channel = manager?.initialize(this, mainLooper, null) channel?.also { channel -> receiver = WiFiDirectBroadcastReceiver(manager, channel, this) } }
جاوا
WifiP2pManager manager; Channel channel; BroadcastReceiver receiver; ... @Override protected void onCreate(Bundle savedInstanceState){ ... manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); channel = manager.initialize(this, getMainLooper(), null); receiver = new WiFiDirectBroadcastReceiver(manager, channel, this); ... }
یک فیلتر قصد ایجاد کنید و همان مقاصدی را که گیرنده پخش شما بررسی می کند اضافه کنید:
کاتلین
val intentFilter = IntentFilter().apply { addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION) addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION) addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION) addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION) }
جاوا
IntentFilter intentFilter; ... @Override protected void onCreate(Bundle savedInstanceState){ ... intentFilter = new IntentFilter(); 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); ... }
گیرنده پخش را در متد
onResume()
فعالیت خود ثبت کنید و آن را در متدonPause()
فعالیت خود لغو ثبت کنید:کاتلین
/* register the broadcast receiver with the intent values to be matched */ override fun onResume() { super.onResume() receiver?.also { receiver -> registerReceiver(receiver, intentFilter) } } /* unregister the broadcast receiver */ override fun onPause() { super.onPause() receiver?.also { receiver -> unregisterReceiver(receiver) } }
جاوا
/* register the broadcast receiver with the intent values to be matched */ @Override protected void onResume() { super.onResume(); registerReceiver(receiver, intentFilter); } /* unregister the broadcast receiver */ @Override protected void onPause() { super.onPause(); unregisterReceiver(receiver); }
وقتی یک
WifiP2pManager.Channel
دریافت کردید و یک گیرنده پخش راهاندازی کردید، برنامه شما میتواند با روش Wi-Fi P2P تماس بگیرد و مقاصد Wi-Fi P2P را دریافت کند.برنامه خود را با استفاده از ویژگیهای Wi-Fi P2P با فراخوانی روشهای موجود در
WifiP2pManager
پیادهسازی کنید.
بخشهای بعدی نحوه انجام اقدامات رایج مانند کشف و اتصال به همتایان را شرح میدهد.
همتایان را کشف کنید
برای شناسایی همتایان موجود که در محدوده هستند و برای اتصال در دسترس هستند، با discoverPeers()
تماس بگیرید. فراخوانی این تابع ناهمزمان است و اگر یک WifiP2pManager.ActionListener
ایجاد کرده باشید، یک موفقیت یا شکست با onSuccess()
و onFailure()
به برنامه شما منتقل می شود. متد onSuccess()
فقط به شما اطلاع می دهد که فرآیند کشف موفقیت آمیز بوده است و در صورت وجود هیچ اطلاعاتی در مورد همتایان واقعی که کشف کرده است ارائه نمی دهد. نمونه کد زیر نحوه تنظیم این را نشان می دهد.
کاتلین
manager?.discoverPeers(channel, object : WifiP2pManager.ActionListener { override fun onSuccess() { ... } override fun onFailure(reasonCode: Int) { ... } })
جاوا
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { ... } @Override public void onFailure(int reasonCode) { ... } });
اگر فرآیند کشف موفقیت آمیز باشد و همتایان را شناسایی کند، سیستم قصد WIFI_P2P_PEERS_CHANGED_ACTION
را پخش می کند، که می توانید برای دریافت لیستی از همتایان، آن را در یک گیرنده پخش گوش دهید. هنگامی که برنامه شما هدف WIFI_P2P_PEERS_CHANGED_ACTION
را دریافت کرد، می توانید لیستی از همتاهای کشف شده را با requestPeers()
درخواست کنید. کد زیر نحوه تنظیم این را نشان می دهد.
کاتلین
override fun onReceive(context: Context, intent: Intent) { val action: String = intent.action when (action) { ... WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> { manager?.requestPeers(channel) { peers: WifiP2pDeviceList? -> // Handle peers list } } ... } }
جاوا
PeerListListener myPeerListListener; ... if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // request available peers from the wifi p2p manager. This is an // asynchronous call and the calling activity is notified with a // callback on PeerListListener.onPeersAvailable() if (manager != null) { manager.requestPeers(channel, myPeerListListener); } }
متد requestPeers()
نیز ناهمزمان است و می تواند فعالیت شما را هنگامی که لیستی از همتاها با onPeersAvailable()
موجود است، که در رابط WifiP2pManager.PeerListListener
در دسترس است، اطلاع دهد. متد onPeersAvailable()
یک WifiP2pDeviceList
در اختیار شما قرار می دهد که می توانید آن را تکرار کنید تا همتای مورد نظر را برای اتصال پیدا کنید.
به همتایان متصل شوید
پس از دریافت لیستی از همتایان احتمالی و انتخاب دستگاهی برای اتصال، متد connect()
را برای اتصال به دستگاه فراخوانی کنید. این فراخوانی روش به یک شی WifiP2pConfig
نیاز دارد که حاوی اطلاعاتی درباره دستگاه برای اتصال به آن باشد. WifiP2pManager.ActionListener
می تواند شما را از موفقیت یا شکست اتصال مطلع کند. کد زیر نحوه ایجاد اتصال به یک دستگاه را به شما نشان می دهد.
کاتلین
val device: WifiP2pDevice = ... val config = WifiP2pConfig() config.deviceAddress = device.deviceAddress channel?.also { channel -> manager?.connect(channel, config, object : WifiP2pManager.ActionListener { override fun onSuccess() { //success logic } override fun onFailure(reason: Int) { //failure logic } } )}
جاوا
//obtain a peer from the WifiP2pDeviceList WifiP2pDevice device; WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.deviceAddress; manager.connect(channel, config, new ActionListener() { @Override public void onSuccess() { //success logic } @Override public void onFailure(int reason) { //failure logic } });
انتقال داده ها
پس از برقراری ارتباط، می توانید داده ها را بین دستگاه های دارای سوکت انتقال دهید. مراحل اصلی انتقال داده ها به شرح زیر است:
- یک
ServerSocket
ایجاد کنید. این سوکت منتظر اتصال از یک کلاینت در یک پورت مشخص می شود و تا زمانی که این اتفاق بیفتد مسدود می شود، بنابراین این کار را در یک رشته پس زمینه انجام دهید. - یک
Socket
مشتری ایجاد کنید. مشتری از آدرس IP و پورت سوکت سرور برای اتصال به دستگاه سرور استفاده می کند. - ارسال داده از مشتری به سرور هنگامی که سوکت سرویس گیرنده با موفقیت به سوکت سرور متصل شد، می توانید داده ها را از سرویس گیرنده به سرور با جریان بایت ارسال کنید.
- سوکت سرور منتظر اتصال کلاینت (با متد
accept()
) است. این تماس تا زمانی که یک کلاینت متصل نشود مسدود میشود، بنابراین آن را در یک رشته دیگر فراخوانی کنید. هنگامی که یک اتصال اتفاق می افتد، دستگاه سرور می تواند داده ها را از مشتری دریافت کند.
مثال زیر که از Wi-Fi P2P Demo تغییر یافته است، به شما نشان می دهد که چگونه این ارتباط سوکت سرویس گیرنده-سرور را ایجاد کنید و تصاویر JPEG را از یک کلاینت به یک سرور با یک سرویس انتقال دهید. برای مثال کاری کامل، دمو را کامپایل و اجرا کنید.
کاتلین
class FileServerAsyncTask( private val context: Context, private var statusText: TextView ) : AsyncTask<Void, Void, String?>() { override fun doInBackground(vararg params: Void): String? { /** * Create a server socket. */ val serverSocket = ServerSocket(8888) return serverSocket.use { /** * Wait for client connections. This call blocks until a * connection is accepted from a client. */ val client = serverSocket.accept() /** * If this code is reached, a client has connected and transferred data * Save the input stream from the client as a JPEG file */ val f = File(Environment.getExternalStorageDirectory().absolutePath + "/${context.packageName}/wifip2pshared-${System.currentTimeMillis()}.jpg") val dirs = File(f.parent) dirs.takeIf { it.doesNotExist() }?.apply { mkdirs() } f.createNewFile() val inputstream = client.getInputStream() copyFile(inputstream, FileOutputStream(f)) serverSocket.close() f.absolutePath } } private fun File.doesNotExist(): Boolean = !exists() /** * Start activity that can handle the JPEG image */ override fun onPostExecute(result: String?) { result?.run { statusText.text = "File copied - $result" val intent = Intent(android.content.Intent.ACTION_VIEW).apply { setDataAndType(Uri.parse("file://$result"), "image/*") } context.startActivity(intent) } } }
جاوا
public static class FileServerAsyncTask extends AsyncTask { private Context context; private TextView statusText; public FileServerAsyncTask(Context context, View statusText) { this.context = context; this.statusText = (TextView) statusText; } @Override protected String doInBackground(Void... params) { try { /** * Create a server socket and wait for client connections. This * call blocks until a connection is accepted from a client */ ServerSocket serverSocket = new ServerSocket(8888); Socket client = serverSocket.accept(); /** * If this code is reached, a client has connected and transferred data * Save the input stream from the client as a JPEG file */ 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(); InputStream inputstream = client.getInputStream(); copyFile(inputstream, new FileOutputStream(f)); serverSocket.close(); return f.getAbsolutePath(); } catch (IOException e) { Log.e(WiFiDirectActivity.TAG, e.getMessage()); return null; } } /** * Start activity that can handle the JPEG image */ @Override protected void onPostExecute(String result) { if (result != null) { statusText.setText("File copied - " + result); Intent intent = new Intent(); intent.setAction(android.content.Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse("file://" + result), "image/*"); context.startActivity(intent); } } }
در سرویس گیرنده، با سوکت سرویس گیرنده به سوکت سرور متصل شوید و داده ها را انتقال دهید. این مثال یک فایل JPEG را بر روی سیستم فایل دستگاه مشتری منتقل می کند.
کاتلین
val context = applicationContext val host: String val port: Int val len: Int val socket = Socket() val buf = ByteArray(1024) ... try { /** * Create a client socket with the host, * port, and timeout information. */ socket.bind(null) socket.connect((InetSocketAddress(host, port)), 500) /** * Create a byte stream from a JPEG file and pipe it to the output stream * of the socket. This data is retrieved by the server device. */ val outputStream = socket.getOutputStream() val cr = context.contentResolver val inputStream: InputStream = cr.openInputStream(Uri.parse("path/to/picture.jpg")) while (inputStream.read(buf).also { len = it } != -1) { outputStream.write(buf, 0, len) } outputStream.close() inputStream.close() } catch (e: FileNotFoundException) { //catch logic } catch (e: IOException) { //catch logic } finally { /** * Clean up any open sockets when done * transferring or if an exception occurred. */ socket.takeIf { it.isConnected }?.apply { close() } }
جاوا
Context context = this.getApplicationContext(); String host; int port; int len; Socket socket = new Socket(); byte buf[] = new byte[1024]; ... try { /** * Create a client socket with the host, * port, and timeout information. */ socket.bind(null); socket.connect((new InetSocketAddress(host, port)), 500); /** * Create a byte stream from a JPEG file and pipe it to the output stream * of the socket. This data is retrieved by the server device. */ OutputStream outputStream = socket.getOutputStream(); ContentResolver cr = context.getContentResolver(); InputStream inputStream = null; inputStream = cr.openInputStream(Uri.parse("path/to/picture.jpg")); while ((len = inputStream.read(buf)) != -1) { outputStream.write(buf, 0, len); } outputStream.close(); inputStream.close(); } catch (FileNotFoundException e) { //catch logic } catch (IOException e) { //catch logic } /** * Clean up any open sockets when done * transferring or if an exception occurred. */ finally { if (socket != null) { if (socket.isConnected()) { try { socket.close(); } catch (IOException e) { //catch logic } } } }