Table of Contents

Labs 05,06. Permissions

Task 1 - List permissions, packages, features from CLI (2p)

In the command line (adb shell):

Hint: pm commands.

Task 2 - MyCamera application (7p)

Implement an application MyCamera that captures photos and saves them full-sized on the SDCARD (/sdcard/Pictures/). Hint: Use this tutorial (Sections: Save the full-size photo, Decode a scaled image).

The application will contain an Activity called MainActivity that will capture the photo and display it. The activity will include a Button and an ImageView. When pressing the Button, the camera should appear to let the user take a photo. Then, the photo will be displayed in the ImageView.

Hint: Use Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) to obtain the directory /sdcard/Pictures. Also, when specifying the provider's external path use “Pictures”.

The camera is started using an Intent with the action MediaStore.ACTION_IMAGE_CAPTURE. In onActivityResult, if the request was successful, display the picture.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode, resultCode, data);
        // Check which request we're responding to
        if (requestCode == REQUEST_TAKE_PHOTO) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                setPic();
            }
        }
    }

Declare the necessary permissions and request them at runtime. You will need the dangerous permissions: android.permission.CAMERA and android.permission.WRITE_EXTERNAL_STORAGE.

Task 3 - Custom Permissions (7p)

Extend the previous application (MyCamera) by adding a new Activity called DisplayPictureActivity and move the ImageView in this activity. Also move the method that displays the picture (setPic()) in this activity.

DisplayPictureActivity is started from MainActivity using an Intent, containing the path of the photo that was just taken as extra. The displayPicture() method is called from onActivityResult, after the picture has been captured and saved.

    private void displayPicture(){
        Intent intent = new Intent();
        intent.setAction("com.smd.lab5.mycamera.startDisplayPictureActivity");
        intent.putExtra("photoPath", mCurrentPhotoPath);
        startActivity(intent);
    }

DisplayPictureActivity must have an intent filter (with the same action) defined in the Manifest:

    <intent-filter>
        <category android:name="android.intent.category.DEFAULT" />
        <action android:name="com.smd.lab5.mycamera.startDisplayPictureActivity" />
    </intent-filter>

In onCreate() method of DisplayPictureActivity, get the Intent and extract the photo path from the Intent. Do NOT call setPic() from onCreate() because the ImageView does not have a width and height yet. setPic() must be called from onWindowFocusChanged:

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (photoPath != null){
            setPic();
        }
    }

If the Intent does not contain an extra, use this method to obtain the path of the last photo in the folder.

    public String lastFilePath() {
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File[] files = storageDir.listFiles(new FileFilter() {
            public boolean accept(File file) {
                return file.isFile();
            }
        });
        long lastMod = Long.MIN_VALUE;
        File choice = null;
        for (File file : files) {
            if (file.lastModified() > lastMod) {
                choice = file;
                lastMod = file.lastModified();
            }
        }
        return choice.getAbsolutePath();
    }

Add a custom permission in the Manifest file of MyCamera (permission tree, permission group and the actual permission). The permission must have the protection level dangerous. In the Manifest, request the new permission for starting the DisplayPictureActivity (android:permission).

Create another application UseMyCamera. In the activity include a Button which will be used to start the activity of the application MyCamera.

For this, we will use an implicit intent for launching the DisplayPictureActivity from the first application:

Intent i = new Intent();
i.setAction("startDisplayPictureActivity"); 
startActivity(i);

Run the application. When pressing the button you should get a SecurityException (Permission Denied). For solving this, use the declared permission in the manifest of the second application. Also, you need to request the permission at runtime because it is a dangerous permission.

Task 4 - Boot completed (4p)

Extend UseMyCamera application, to receive BOOT COMPLETED broadcast message. Implement a broadcast receiver for the action android.intent.action.BOOT_COMPLETED. In order to receive those messages, you need to declare the permission android.permission.RECEIVE_BOOT_COMPLETED in the Manifest.