This example shows how to perform a HTTP GET request.
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.lang import Exception, Math, String from java.io import BufferedInputStream, FileNotFoundException, IOException from java.net import HttpURLConnection, URL from android.app import Activity from android.content import Context from android.graphics import BitmapFactory from android.os import Build, Bundle from android.view import View, ViewGroup from android.widget import Button, LinearLayout, ImageView, Toast from android.net import ConnectivityManager from android.util import Log
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 HTTPGetActivity(Activity): __interfaces__ = [View.OnClickListener]
The activity implements an interface to handle clicks on views.
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 a reference to the connectivity service and setting up the user interface.
@args(void, [Bundle]) def onCreate(self, bundle): Activity.onCreate(self, bundle)
We obtain an object that gives us access to the connectivity service. Since the method used to obtain this object does not specify the specific type of the manager object, we need to cast it explicitly to the correct type so that we can access its methods.
service = self.getSystemService(Context.CONNECTIVITY_SERVICE) self.manager = CAST(service, ConnectivityManager)
We set up the user interface: just a button that is used to request an image to be fetched from a website, and a view that is used to display it.
self.button = Button(self) self.button.setText("Fetch (HTTP GET)") self.button.setOnClickListener(self) self.imageView = ImageView(self)
The views are placed in a layout that is the main content shown by the activity.
layout = LinearLayout(self) layout.setLayoutParams(ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) layout.setOrientation(LinearLayout.VERTICAL) layout.addView(self.button) layout.addView(self.imageView) self.setContentView(layout)
We implement the onClick method to provide the View.OnClickListener interface that we declared earlier. This responds to clicks on the button that we created in the previous method.
def onClick(self, view):
Currently, we have only implemented support for older versions of the connectivity API, so we check for those before checking whether the device has access to the Internet.
if Build.VERSION.SDK_INT < 23: info = self.manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) if info == None or not info.isConnected(): Toast.makeText(self, "Not connected", Toast.LENGTH_SHORT).show() return else: Toast.makeText(self, "Not supported\nPlease update the example code.", Toast.LENGTH_SHORT).show() return
If the device is able to access online resources, we use it to fetch an image from a website. We specify the URL of the resource and use the URL object to open a connection to the server hosting it. We cast the connection object to a HttpURLConnection object so that we can enable request redirections.
url = URL("http://www.boddie.org.uk/david/www-repo/Personal/Updates/2016/images/duck-small.png") connection = CAST(url.openConnection(), HttpURLConnection) connection.setInstanceFollowRedirects(True)
We obtain the length of the content from the connection and check to see if it is reasonable, showing a message and returning if not.
length = connection.getContentLength() if length <= 0: Toast.makeText(self, "Invalid content length", Toast.LENGTH_SHORT).show() return
We use a stream to read the content, storing it in an array of the required length or showing an error message and returning if the stream cannot be opened.
try: stream = BufferedInputStream(connection.getInputStream()) except FileNotFoundException: Toast.makeText(self, "Resource not found", Toast.LENGTH_SHORT).show() return a = array(byte, length) total = 0
We loop until we have read all the content, storing new data after that we have already read, and requesting as much as possible. When all the data has been read, we close the stream.
while total < length: total += stream.read(a, total, length - total) stream.close()
Since the content should be a PNG image, we decode it using a static BitmapFactory method, but for safety we only set the image on the ImageView if we obtain a valid bitmap.
bitmap = BitmapFactory.decodeByteArray(a, 0, total) if bitmap != None: self.imageView.setImageBitmap(bitmap)