Homework 6 - CatGrabber App
We will create an application that downloads cat images from the web (https://cataas.com/) and displays them as ImageViews inside a GridView, forming a sort of gallery.
The user can enter the number of cats to download, and a background service will download them and create a broadcast for each downloaded image.
1. Showing a Grid of ImageViews ( 1 pt)
Your MainActivity should include a GridView (don't forget to add constraints if using ConstraintLayout!), something like:
<GridView android:id="@+id/cat_gridview" android:layout_width="0dp" android:layout_height="0dp" android:columnWidth="190dp" android:horizontalSpacing="10dp" android:numColumns="auto_fit" android:stretchMode="none" android:verticalSpacing="10dp" />
The contents of the GridView will be filled using a custom Adapter. Createa a Class called CatAdapter that extends BaseAdapter(), with a field member var imageList = ArrayList<Bitmap>()
.
Implement the getItem(), getItemId(), getCount() methods similar to previous labs. For getView() function, you can use the following snippet, which constructs an ImageView from the item in the ArrayList.
val imageView = ImageView(parent?.context) imageView.setImageBitmap(imageList[position]) imageView.setScaleType(ImageView.ScaleType.FIT_CENTER) imageView.layoutParams = AbsListView.LayoutParams(400,400) imageView.scaleType = ImageView.ScaleType.CENTER_CROP imageView.setPadding(5, 5, 5 ,5) return imageView
2. Cat Downloader Service
The user will enter a number (how many cats to grab) into the EditText, when the user clicks a button in Activity, a (started) service is launched (as discussed in lecture 6). The intent which launches the service should contain the editText number value as an extra.
2.1 Downloading cats (1 pt)
The service should request as many images as specified in the number extra from https://cataas.com/cat?width=400&height=400, which returns a random image of the specified size.
Apps which use internet need to declare android.permission.INTERNET
permission in their manifest. (This is a "not-dangeours" permission, so it is granted automatically.)
- You download an image and decode it into a Bitmap using
val url = URL("some_url_here") val fullBitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream())
- It may be useful to scale the image before adding it to the intent extras, as we did in the lab.
- You may use a for-loop, but Kotlin
repeat( n ){ //some code }
is useful in this case also.
2.2 Broadcasting service results (2pt)
- For each downloaded Bitmap, the service should send a broadcast. The sent broadcast should include a Bitmap extra (the downloaded file). Note that extras are limited by size.
- MainActivity should register a BroadcastReceiver that can receive the broadcasts sent from the service (use an IntentFilter to identify the correct broadcasts). Upon receiving a broadcast, the Bitmap extra contained in the Intent should be added to the adapters imageList and notifyDatasetChanged() should be called.
3 Multithread mode (1pt)
Update the App, so that using a checkbox View, the user can mark whether the service should download the cats sequentially in one thread or whether to create a new thread for each request.
- Use intent extras to pass the checkbox value to the service
- In the service, based on the checkbox value run either a single thread or start multiple threads.
Troubleshooting
Sometimes, it seems Emulators randomly lose internet connection. This is indicated by "x" symbols on the Wifi/4G icons on the top bar. You can verify if your emulator has internet connectivity by e.g. trying to visit a webpage from the browser. To fix it, you can try fully closing the emulator. From Android Studio AVD there is also an option for "cold boot". If you find a good solution for this, you may share it with all of us on the google group!