This shows you the differences between two versions of the page.
— |
smd:laboratoare:old:05 [2019/03/06 14:58] (current) adriana.draghici created |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ===== Labs 05,06. Permissions ===== | ||
+ | |||
+ | |||
+ | === Task 1 - List permissions, packages, features from CLI (2p) === | ||
+ | |||
+ | In the command line (**adb shell**): | ||
+ | * List all permissions currently known by the system. | ||
+ | * List all permission groups known by the system. | ||
+ | * Display more information about the permissions using **-f** (defining package, label, description and protection level). | ||
+ | * Display all permissions in **android.permission-group.PHONE**. | ||
+ | * Display detailed information about all permissions in **android.permission-group.PHONE**. | ||
+ | * List all packages installed in the system. | ||
+ | * List all features of the system (hardware & software). | ||
+ | |||
+ | Hint: [[http://androiddoc.qiniudn.com/tools/help/shell.html#pm|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 [[https://developer.android.com/training/camera/photobasics.html|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. | ||
+ | |||
+ | <code> | ||
+ | @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(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | 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. | ||
+ | |||
+ | <code> | ||
+ | private void displayPicture(){ | ||
+ | Intent intent = new Intent(); | ||
+ | intent.setAction("com.smd.lab5.mycamera.startDisplayPictureActivity"); | ||
+ | intent.putExtra("photoPath", mCurrentPhotoPath); | ||
+ | startActivity(intent); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | **DisplayPictureActivity** must have an intent filter (with the same action) defined in the Manifest: | ||
+ | |||
+ | <code> | ||
+ | <intent-filter> | ||
+ | <category android:name="android.intent.category.DEFAULT" /> | ||
+ | <action android:name="com.smd.lab5.mycamera.startDisplayPictureActivity" /> | ||
+ | </intent-filter> | ||
+ | </code> | ||
+ | |||
+ | 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**: | ||
+ | |||
+ | <code> | ||
+ | @Override | ||
+ | public void onWindowFocusChanged(boolean hasFocus) { | ||
+ | super.onWindowFocusChanged(hasFocus); | ||
+ | if (photoPath != null){ | ||
+ | setPic(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | If the Intent does not contain an extra, use this method to obtain the path of the last photo in the folder. | ||
+ | |||
+ | <code> | ||
+ | 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(); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | 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: | ||
+ | |||
+ | <code> | ||
+ | Intent i = new Intent(); | ||
+ | i.setAction("startDisplayPictureActivity"); | ||
+ | startActivity(i); | ||
+ | </code> | ||
+ | |||
+ | 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. | ||
+ | |||