This example shows how to obtain information about the network connections of a device.
Note that, in order to access the network information, the application needs to be built with the android.permission.INTERNET permission. The build script takes care of this.
We import the classes and modules that will be needed by the application. The most relevant are the classes from the java.net module.
from java.net import NetworkInterface, SocketException
from java.util import LinkedList
from android.os import AsyncTask
from android.widget import Adapter, ListView
from serpentine.activities import Activity
from serpentine.adapters import StringListAdapter
According to the NetworkOnMainThreadException
documentation, on Android
Honeycomb or higher, network operations need to be done in a thread other than
the GUI thread, so we also need to import the AsyncTask
class.
We define a class based on the standard Activity class. This represents the application, and will be used to present a graphical interface to the user.
class NetworkInfoActivity(Activity):
The initialisation method simply calls the base class implementation.
def __init__(self):
Activity.__init__(self)
The onCreate method calls the base class implementation before obtaining information about the network interfaces and setting up the user interface.
def onCreate(self, bundle):
Activity.onCreate(self, bundle)
The user interfaces consists of a list of strings shown in a
ListView
widget. The view is populated by an adapter.
self.adapter = StringListAdapter(None)
listView = ListView(self)
listView.setAdapter(self.adapter)
self.setContentView(listView)
We create an instance of an AsyncTask
subclass and start executing
it, passing an empty array of integers since we do not really have any
data to process.
self.task = Task(listView)
self.task.execute(array(int, 0))
We define a Task class based on the standard AsyncTask class. This encapsulates the processing that we want to perform in the background. The equivalent Java class is a template class with the following parameters: Params, Progress and Result.
class Task(AsyncTask):
__item_types__ = [int, int, LinkedList(str)]
The initialisation method accepts the ListView widget that we want to update, storing it for later reference.
@args(void, [ListView])
def __init__(self, view):
AsyncTask.__init__(self)
self.view = view
We define the doInBackground method with the code we want to be executed in the background. In this example, we compile a list of strings containing the available network interfaces and the addresses assigned to them.
@args(Result, [[Params]])
def doInBackground(self, params):
strings = []
try:
interfaces = NetworkInterface.getNetworkInterfaces()
while interfaces.hasMoreElements():
We obtain an interface and the addresses assigned to it.
interface = interfaces.nextElement()
addresses = interface.getInetAddresses()
if addresses.hasMoreElements():
If the interface has at least one address assigned to it then we show the interface name and each of the addresses.
strings.add(interface.getDisplayName())
while addresses.hasMoreElements():
address = addresses.nextElement()
values = {address.getHostName(),
address.getCanonicalHostName(),
address.getHostAddress()}
for value in values:
strings.add(" " + value)
If information about the network interfaces could not be obtained then we simply add a message to the list.
except SocketException:
strings.add("No interfaces available")
return strings
The onPostExecute method is called with the value we returned from the previous method. This lets us decide how the result of the processing is used. Here, we display the string we created in the previous method in the TextView instance that we passed to the Task instance on its creation.
@args(void, [Result])
def onPostExecute(self, result):
adapter = StringListAdapter(result)
self.view.setAdapter(adapter)