Wi-Fi Direct (P2P) consente ai dispositivi con l'hardware appropriato di connettersi direttamente tramite Wi-Fi senza un punto di accesso intermedio. Con queste API, puoi rilevare e connettersi ad altri dispositivi quando ciascuno supporta Wi-Fi P2P, quindi comunicano tramite una connessione veloce da distanze molto più lunghe rispetto a una Connessione Bluetooth. Ciò è utile per le applicazioni che condividono dati tra come un gioco multiplayer o un'applicazione di condivisione di foto.
Le API Wi-Fi P2P sono costituite dai seguenti componenti principali:
- Metodi che consentono di scoprire, richiedere e connettersi ai peer, che sono
definita nel
WifiP2pManager
. - Listener che ti consentono di ricevere notifiche relative a esito positivo o negativo di
Chiamate al metodo
WifiP2pManager
. Quando chiami i metodiWifiP2pManager
, ogni può ricevere un listener specifico passato come parametro. - Intent che ti informano di eventi specifici rilevati dal Wi-Fi P2P ad esempio un'interruzione della connessione o un peer rilevato di recente.
Spesso utilizzerai insieme questi tre componenti principali delle API. Per
Ad esempio, puoi fornire una
WifiP2pManager.ActionListener
a una chiamata a
discoverPeers()
in modo che
ActionListener.onSuccess()
e
ActionListener.onFailure()
possono inviarti notifiche. R
WIFI_P2P_PEERS_CHANGED_ACTION
viene trasmesso anche se il metodo discoverPeers()
rileva che l'intent
l'elenco di app peer è cambiato.
Panoramica dell'API
La classe WifiP2pManager
fornisce metodi per consentirti di interagire con il
L'hardware Wi-Fi sul tuo dispositivo per, ad esempio, rilevare contenuti e connettersi ad altri utenti.
Sono disponibili le seguenti azioni:
Tabella 1. Metodi Wi-Fi P2P
Metodo | Descrizione |
initialize()
|
Registra l'applicazione con il framework Wi-Fi. Chiama prima chiamata a qualsiasi altro metodo Wi-Fi P2P. |
connect()
|
Avvia una connessione peer-to-peer con un dispositivo con la configurazione specificata. |
cancelConnect()
|
Annulla qualsiasi negoziazione con il gruppo peer-to-peer in corso. |
requestConnectInfo()
|
Consente di richiedere le informazioni di connessione di un dispositivo. |
createGroup()
|
Crea un gruppo peer-to-peer con il dispositivo corrente come proprietario del gruppo. |
removeGroup()
|
Rimuove il gruppo peer-to-peer corrente. |
requestGroupInfo()
|
Consente di richiedere informazioni sul gruppo peer-to-peer. |
discoverPeers()
|
Avvia il rilevamento dei peer. |
requestPeers()
|
Consente di richiedere l'elenco corrente dei peer rilevati. |
WifiP2pManager
metodi consentono
trasmetti a un listener, in modo che il framework Wi-Fi P2P possa notificare la tua attività
lo stato di una chiamata. Le interfacce disponibili e le interfacce corrispondenti
Chiamate metodo WifiP2pManager
che utilizzano i listener sono descritti nella tabella 2.
Tabella 2. Listener P2P Wi-Fi
Interfaccia dell'ascoltatore | Azioni associate |
WifiP2pManager.ActionListener
|
connect() , cancelConnect() ,
createGroup() , removeGroup() e
discoverPeers()
|
WifiP2pManager.ChannelListener
|
initialize()
|
WifiP2pManager.ConnectionInfoListener
|
requestConnectInfo()
|
WifiP2pManager.GroupInfoListener
|
requestGroupInfo()
|
WifiP2pManager.PeerListListener
|
requestPeers()
|
Le API Wi-Fi P2P definiscono gli intent che vengono trasmessi quando un determinato Wi-Fi P2P si verificano, ad esempio, il rilevamento di un nuovo peer o la connessione Wi-Fi di un dispositivo modifiche dello stato. Puoi registrarti per ricevere questi intent nella tua richiesta tramite creazione di un broadcast receiver che gestisce questi intent:
Tabella 3. Intent P2P Wi-Fi
Intenzione | Descrizione |
WIFI_P2P_CONNECTION_CHANGED_ACTION
|
Trasmetti quando lo stato della connessione Wi-Fi del dispositivo cambia. |
WIFI_P2P_PEERS_CHANGED_ACTION
|
Trasmetti quando chiami discoverPeers() . Di solito
chiama requestPeers() per ricevere un elenco aggiornato di app peer se
a gestire questo intent nella tua applicazione.
|
WIFI_P2P_STATE_CHANGED_ACTION
|
Trasmetti quando il Wi-Fi P2P è attivato o disattivato sul dispositivo. |
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
|
Trasmetti quando i dettagli di un dispositivo cambiano, ad esempio il nome. |
Creare un broadcast receiver per gli intent P2P Wi-Fi
Un broadcast receiver consente di ricevere gli intent trasmessi da Android di sistema, in modo che la tua applicazione possa rispondere agli eventi che ti interessano in. Passaggi di base per creare un broadcast receiver per gestire il Wi-Fi P2P sono i seguenti:
Crea una classe che amplia le
BroadcastReceiver
. Per la classe userai i parametri perWifiP2pManager
,WifiP2pManager.Channel
e l'attività che questo broadcast receiver in cui eseguire la registrazione. In questo modo il broadcast receiver può inviare aggiornamenti attività, nonché avere accesso all'hardware Wi-Fi e a una canale, se necessario.Nel broadcast receiver, cerca gli intent che ti interessano nel
onReceive()
. Esegui le azioni necessarie in base all'intento ricevuto. Ad esempio, se il broadcast receiver riceve un Per intentWIFI_P2P_PEERS_CHANGED_ACTION
, puoi chiamare l'eventorequestPeers()
per ottenere un elenco dei peer attualmente rilevati.
Il seguente codice mostra come creare un tipico broadcast receiver. La
Il broadcast receiver accetta un oggetto WifiP2pManager
e un'attività come argomenti
e li utilizza per eseguire in modo appropriato le azioni necessarie
il broadcast receiver riceve un intent:
Kotlin
/** * 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 } } } }
Java
/** * 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 } } }
Sui dispositivi con Android 10 e versioni successive, vengono mostrati i seguenti intent di trasmissione: non persistente:
WIFI_P2P_CONNECTION_CHANGED_ACTION
- Le applicazioni possono utilizzare
requestConnectionInfo()
,requestNetworkInfo()
, oppurerequestGroupInfo()
per recuperare le informazioni di connessione corrente. WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
- Le applicazioni possono utilizzare
requestDeviceInfo()
per recuperare le informazioni di connessione correnti.
Crea un'applicazione Wi-Fi P2P
La creazione di un'applicazione Wi-Fi P2P comporta la creazione e la registrazione di una trasmissione un ricevitore per la tua applicazione, scoprendo peer, connettendoti a un peer trasferire i dati a un peer. Le sezioni seguenti descrivono la procedura da seguire.
Configurazione iniziale
Prima di utilizzare le API Wi-Fi P2P, devi assicurarti che l'applicazione possa
accedere all'hardware e che il dispositivo supporti il protocollo Wi-Fi P2P. Se
Il Wi-Fi P2P è supportato, puoi ottenere un'istanza di WifiP2pManager
, creare
e registra il broadcast receiver, quindi inizia a utilizzare le API Wi-Fi P2P.
Richiedi l'autorizzazione per utilizzare l'hardware Wi-Fi sul dispositivo e dichiara disporre della versione minima corretta dell'SDK in Android manifest:
<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" />
Oltre alle autorizzazioni precedenti, le API seguenti richiedono anche Modalità da attivare:
Controlla se il Wi-Fi P2P è attivo e supportato. Un buon punto per controllare è nel tuo broadcast receiver quando riceve Intenzione
WIFI_P2P_STATE_CHANGED_ACTION
. Invia una notifica per l'attività del P2P Wi-Fi e reagire di conseguenza:Kotlin
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 } } } } ... }
Java
@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 } } ... }
Nella sezione
onCreate()
, ottieni un'istanza diWifiP2pManager
e registra la tua applicazione con il framework Wi-Fi P2P chiamandoinitialize()
. Questo metodo restituisce unWifiP2pManager.Channel
, che viene utilizzato per connettere la tua applicazione al Framework P2P Wi-Fi. Devi anche creare un'istanza della trasmissione ricevitore con gli oggettiWifiP2pManager
eWifiP2pManager.Channel
insieme con riferimento alla tua attività. Ciò consente al tuo broadcast receiver di avvisa la tua attività di eventi interessanti e aggiornali di conseguenza. Inoltre, consente di modificare lo stato Wi-Fi del dispositivo se necessario:Kotlin
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) } }
Java
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); ... }
Crea un filtro per intent e aggiungi gli stessi intent del broadcast receiver verifica:
Kotlin
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) }
Java
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); ... }
Registra il broadcast receiver nel
onResume()
del tuo dell'attività e annullarne la registrazione MetodoonPause()
di attività:Kotlin
/* 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) } }
Java
/* 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); }
Dopo aver ricevuto un
WifiP2pManager.Channel
e configurato una trasmissione ricevitore, l'applicazione può effettuare chiamate metodo Wi-Fi P2P e ricevere Intent P2P.Implementa la tua applicazione, utilizzando le funzionalità Wi-Fi P2P chiamando il metodo in
WifiP2pManager
.
Le prossime sezioni descrivono come eseguire azioni comuni come scoperta e e la connessione con i colleghi.
Scopri le app peer
Chiama discoverPeers()
per rilevare le app peer disponibili che sono nel raggio d'azione e sono disponibili
per la connessione. La chiamata a questa funzione è asincrona e ha un esito positivo
l'errore viene comunicato alla tua applicazione con onSuccess()
e onFailure()
se hai creato un WifiP2pManager.ActionListener
. Solo il metodo onSuccess()
ti comunica che il processo di rilevamento è riuscito e non fornisce
informazioni sulle app peer effettive rilevate, se presenti. Le seguenti
un esempio di codice mostra come configurarlo.
Kotlin
manager?.discoverPeers(channel, object : WifiP2pManager.ActionListener { override fun onSuccess() { ... } override fun onFailure(reasonCode: Int) { ... } })
Java
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { ... } @Override public void onFailure(int reasonCode) { ... } });
Se il processo di rilevamento ha esito positivo e rileva i colleghi, il sistema trasmette il
Intent WIFI_P2P_PEERS_CHANGED_ACTION
, che puoi ascoltare in una trasmissione
per ottenere un elenco di app peer. Quando l'applicazione riceve
WIFI_P2P_PEERS_CHANGED_ACTION
intent, puoi richiedere un elenco dei
peer con requestPeers()
. Il seguente codice mostra come eseguire la configurazione.
Kotlin
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 } } ... } }
Java
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); } }
Anche il metodo requestPeers()
è asincrono e può notificare la tua attività
quando è disponibile un elenco di app peer con
onPeersAvailable()
,
che è definito nell'interfaccia WifiP2pManager.PeerListListener
. La
Il metodo onPeersAvailable()
ti fornisce un
WifiP2pDeviceList
, che
puoi eseguire l'iterazione per trovare il peer a cui connetterti.
Connettiti con altre persone
Dopo aver ottenuto un elenco di possibili app peer e aver selezionato un dispositivo da connettere
a, chiama il metodo connect()
per connetterti al dispositivo. Questa chiamata al metodo
richiede un WifiP2pConfig
contenente informazioni sul dispositivo a cui connettersi.
WifiP2pManager.ActionListener
può avvisarti se la connessione è riuscita o
errore. Il seguente codice mostra come creare una connessione a un dispositivo.
Kotlin
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 } } )}
Java
//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 } });
Trasferisci dati
Una volta stabilita una connessione, puoi trasferire i dati tra i dispositivi con prese di corrente. I passaggi di base per il trasferimento dei dati sono i seguenti:
- Crea una
ServerSocket
. Questo socket attende una connessione da un client su una porta specificata e si blocca esegui questa operazione in un thread in background. - Crea un client
Socket
. Il cliente utilizza Indirizzo IP e porta del socket del server per la connessione al dispositivo server. - Inviare i dati dal client al server. Quando il socket del client ha esito positivo si connette al socket del server, puoi inviare i dati dal client con flussi di byte.
- Il socket del server attende una connessione client (con il
accept()
). Questa chiamata blocchi fino a quando un client non si connette, quindi chiamalo in un altro thread. Quando , il dispositivo server può ricevere i dati dal client.
L'esempio seguente, modificato dalla versione Wi-Fi P2P Demo, mostra come creare questa comunicazione e trasferimento socket client-server Immagini JPEG da un client a un server con un servizio. Per un lavoro completo esempio, compila ed esegui la demo.
Kotlin
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) } } }
Java
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); } } }
Sul client, connettiti al socket del server con un socket client e trasferisci e i dati di Google Cloud. In questo esempio viene trasferito un file JPEG nel file system del dispositivo client.
Kotlin
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() } }
Java
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 } } } }