Institute of Computer Science
  1. Courses
  2. 2022/23 fall
  3. Mobile Application Development (LTAT.06.021)
ET
Log in

Mobile Application Development 2022/23 fall

  • Main
  • Lectures
  • Labs
  • Homeworks & Assignments
  • Task submission
  • Extra Materials
  • Best Practices
  • Results
  • Quizes
  • Projects
    • Presentations & Report
    • Teams & Topics
    • Grading & Submission

Mini project: Recipes app with Camera

Deadline: 30.10.2022

This task is to be solved with a co-student (both should submit the same source-code).

In this mini-project, we shall create a more complete Recipes App, involving local database storage and camera-based images.

The app allows the user to :

  • See a list of recipes when launching the app (5 pts)
    • Each item in the list has a text title and may also show an image thumbnail.
  • The user can click on a recipe to see its details (3 pts)
    • Details must include:
      • A Title, recipe steps, an Image* (*if the recipe has one)
  • User can create new recipes (3 pts)
    • Clicking on a separate button in the recipe list takes the user to a new screen view for creating the recipe
    • They must be able to enter a name and recipe instructions (both always required).
  • User has the option to attach a picture while creating a Recipe (4 pts)
    • A button should allow the user to use the systems Camera app to take a picture.
    • After taking a picture, the Image should be visible in the New Recipe view.
    • The user can finalize creating the recipe by clicking a button, which returns them to the lists. where the new recipe should appear (including the image, if the user took one)

Technical requirements:

  • The recipes should be stored (and queried) using a Room DB
    • For images, you should only store the file path / file URI in the DB. The actual Image file is stored on the filesystem.
  • The list should be implemented using RecyclerView
  • The Photo taking should be implemented using Intents (see below for guideline)

You should aim for a stable and consistent user experience!

  • The application should not crash under typical usage and circumstances (e.g. when user cancels some action or leaves some data not entered etc etc).
  • For an example solution and some more tips, check out the ending of the Lab 6 video recording

How to implement the camera/picture feature.

General strategy is the following. A more detailed guide is below.

  • Define an Intent for taking a picture with the Camera app.
    • Attach to this intent a new Files path (you define it). The Camera app will save the picture there.
  • Launch the Intent
  • Once you get a result back from launching the intent, check that the result was OK, then you can use the File path you defined earlier, to load a Bitmap, store this path in the Room DB, etc.

Detailed Guide

To make this work, our App needs to define a ContentProvider which the Camera app will use to store files into our apps file storage space.

  • For this, you need to define a content provider in the AndroidManifest.xml:
        <!-- Below code has to go inside of application tag, similar to activity -->
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="ee.ut.cs.recipeappp.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/fileprovider" />
        </provider>
  • The above definition links to a XML resource file, you need to create it /res/xml/fileprovider.xml, its contents should be:
    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <!-- The external-files-path DOES NOT require external storage permissions. -->
        <external-files-path
            name="images"
            path="Pictures" />
    </paths>
  • Next, let's see how we can to define the File-s location which we should pass to the Intent.

Defining the Intent looks something like this:

        // Define the file using a custom function getPhotoFile() (see below)
        val photoFile = getPhotoFile("myFileName.jpg")
        val fileUri = FileProvider.getUriForFile(requireContext(), "ee.ut.cs.recipeappp.fileprovider", photoFile)

        val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); 

        launcher.launch(takePictureIntent) // use a registerForActivityResult(.. ) launcher
  • The above code relies on this function:
    /**
     * Returns the File for a photo stored on disk given the fileName.
     * Creating the storage directory if it does not exist:*/
    fun getPhotoFile(fileName: String): File {
        // Get safe storage directory for photos. Use `getExternalFilesDir` on Context to access package-specific directories.
        // This way, we don't need to request external read/write runtime permissions.
        val mediaStorageDir: File = context?.getExternalFilesDir(Environment.DIRECTORY_PICTURES)!!

        if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()) {
            Log.d(APP_TAG, "failed to create directory")
        }
        return File(mediaStorageDir.path + File.separator + fileName)
    }
  • If the above Intent is launched and picture is taken, then we can try to load the image once the launchers callback is invoked.
    • The load a Bitmap from a File path you can:
    val bmp = BitmapFactory.decodeFile(pictureFilePath)

More tips

  • Store the File path as a String (e.g. using File-s absolutePath method).
  • Don't forget to scale down the image before showing it in UI.
  • Because we want 1 picture per recipe, you have to make sure you are creating unique filenames for each new recipe. One strategy is to use of timestamps in the filename to ensure uniqueness.
  • Institute of Computer Science
  • Faculty of Science and Technology
  • University of Tartu
In case of technical problems or questions write to:

Contact the course organizers with the organizational and course content questions.
The proprietary copyrights of educational materials belong to the University of Tartu. The use of educational materials is permitted for the purposes and under the conditions provided for in the copyright law for the free use of a work. When using educational materials, the user is obligated to give credit to the author of the educational materials.
The use of educational materials for other purposes is allowed only with the prior written consent of the University of Tartu.
Terms of use for the Courses environment