Cdacians

Cdacians
Cdacians

Friday, 14 September 2012

Click-Pick-Set – Simple Camera Activity


Click-Pick-Set – Simple Camera Activity
This post is all about how to use camera activity in your Android application. Let me give a quick glance of what we are going to develop today. We will have one image view and two buttons (one for taking picture and other for setting wallpaper) in our application. When you click Take photo button, will take you to default camera present in your device and capture the image. You can set the clicked image as your wallpaper just by clicking Set as Wallpaper button. Does it sound interesting?.. I hope YES.. :)
Let’s begin…
Layout creation:
Create a simple layout which has a TextView and ImageView placed in relative layout where the controls are placed in relative position to the parent window.
New Visitor? Like what you read? Then do subscribe to 
TextView – Displays the text ‘No image’ when there is no image captured yet.
ImageView – Displays the captured image

Create two Buttons – One to take picture and other to set captured image as wallpaper
Final Layout XML :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal|center_vertical"
    android:orientation="vertical" >
 
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="6"
        android:gravity="center_horizontal|center_vertical" >
 
        <TextView
            android:id="@+id/field"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="No Image" />
 
        <ImageView
            android:id="@+id/image"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </RelativeLayout>
 
    <Button
        android:id="@+id/button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Take Photo" />
 
    <Button
        android:id="@+id/button1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Set as Wallpaper" />
 
</LinearLayout>
Application layout:
We are done with design, yet to start code the logic. I would recommend you to download the source code right away to proceed with the listings given below. Create following objects right under the Activity class to refer the controls:
1
2
3
4
protected Button imgButton;//To refer image button
protected ImageView image;//To refer image view
protected TextView field;//To refer textview   
protected Button wallpapaerBtn;//To refer wallpaper button
Create following instance variables to support the logic under the objects we created:
1
2
3
4
private boolean imgCapFlag = false;
protected boolean taken;
protected static final String PHOTO_TAKEN = "photo_taken";
protected String path;
Assign the controls to the respective objects we created above. Set the OnClickListener for Take Photo and Set as Wallpaper buttons. Set the path where the capture image will be stored. You need to explicitly create a folder named ‘images’ under the root of SD card.
1
2
3
4
5
6
7
8
9
10
11
12
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        image = (ImageView) findViewById(R.id.image);
        field = (TextView) findViewById(R.id.field);
        imgButton = (Button) findViewById(R.id.button);
        wallpapaerBtn = (Button) findViewById(R.id.button1);
        imgButton.setOnClickListener(new ButtonClickHandler());
        wallpapaerBtn.setOnClickListener(new ButtonClickHandler1());
        path = Environment.getExternalStorageDirectory()
                                + "/images/make_machine_example.jpg";
    }
Create ButtonHandler class for Take photo button:
1
2
3
4
5
6
7
8
public class ButtonClickHandler implements View.OnClickListener {
public void onClick(View view) {
    //Below log message will be logged when you click Take photo button
    Log.i("AndroidProgrammerGuru", "ButtonClickHandler.onClick()");
    //Call startCameraActivity, an user defined method, going to be created
    startCameraActivity();
    }
}
Create startCameraActivity method which initiates the camera activity:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void startCameraActivity() {
             //Log message
         Log.i("AndroidProgrammerGuru", "startCameraActivity()");
         //Create new file with name mentioned in the path variable
             File file = new File(path);
             //Creates a Uri from a file
         Uri outputFileUri = Uri.fromFile(file);
             //Standard Intent action that can be sent to have the
             //camera application capture an image and return it.
             //You will be redirected to camera at this line
         Intent intent = new Intent(
            android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
             //Add the captured image in the path
         intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
             //Start result method - Method handles the output
             //of the camera activity
         startActivityForResult(intent, 0);
    }
Create onActivityResult method to handle the result of camera activity:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    //Log message
        Log.i("AndroidProgrammerGuru", "resultCode: " + resultCode);
    switch (resultCode) {
        //When user doesn't capture image, resultcode returns 0
        case 0:
        Log.i("AndroidProgrammerGuru", "User cancelled");
        break;
        //When user captures image, onPhotoTaken an user-defined method
        //to assign the capture image to ImageView
            case -1:
        onPhotoTaken();
        break;
    }
}
onPhotoTaken – User defined method to set captured image in the ImageView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void onPhotoTaken() {
        //Log message
    Log.i("AndroidProgrammerGuru", "onPhotoTaken");
    //Flag used by Activity life cycle methods
        taken = true;
    //Flag used to check whether image captured or not
        imgCapFlag = true;
    //BitmapFactory- Create an object
        BitmapFactory.Options options = new BitmapFactory.Options();
    //Set image size
        options.inSampleSize = 4;
    //Read bitmap from the path where captured image is stored
        Bitmap bitmap = BitmapFactory.decodeFile(path, options);
    //Set ImageView with the bitmap read in the prev line
        image.setImageBitmap(bitmap);
        //Make the TextView invisible
    field.setVisibility(View.GONE);
    }
Create ButtonHandler class for Set as Wallpaper button:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class ButtonClickHandler1 implements View.OnClickListener {
  public void onClick(View view) {
    //Log message
        Log.i("AndroidProgrammerGuru", "ButtonClickHandler.onClick()");
    try {
        //Check if image is captured which sets
        //imgCapFlag in onPhotoTaken method
           if (imgCapFlag) {   
                //Create drawable object to convert ImageView to bitmap
        BitmapDrawable drawable = (BitmapDrawable) image
                    .getDrawable();
                //Get bitmap from drawable object
        Bitmap bitmap = drawable.getBitmap();
                //Create WallpaperManager object
        WallpaperManager wallpaperManager = WallpaperManager
                .getInstance(ClickPickSetActivity.this);
                //Set wallpaper with the extracted bitmap
        wallpaperManager.setBitmap(bitmap);
                //Have user informed with a simple toast message
        Toast.makeText(ClickPickSetActivity.this,
           "Wallpaper set : )", Toast.LENGTH_SHORT).show();
           //If image is not captured yet
       } else {
                 //Ask user to capture image
        Toast.makeText(
        ClickPickSetActivity.this,
              "You must capture photo before
                       you try to set wallpaper!",
                          Toast.LENGTH_SHORT).show();
           }
           } catch (Exception e) {
        e.printStackTrace();
           }
    }
}
When you put this application in sleep mode which means you press ‘Home’ button, below method will be called which set the state with key ‘photo_taken’ to true.
1
2
3
protected void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(ClickPickSetActivity.PHOTO_TAKEN, taken);
}
When you open this application(after you pressed ‘Home’ button), application will be resumed which calls the below method:
1
2
3
4
5
6
7
onRestoreInstanceState method calls the onPhotoTaken method
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    Log.i("AndroidProgrammerGuru", "onRestoreInstanceState()");
    if(savedInstanceState.getBoolean(ClickPickSetActivity.PHOTO_TAKEN)){
        onPhotoTaken();
    }
}
You must add following permission in AndroidManifest.xml (Just above application tag) which gives permission to this application to change wallpaper of a device.
1
<uses-permission android:name="android.permission.SET_WALLPAPER" />
Let us check whether the code we typed is working..
Make sure you created folder named ‘images’ right under the root of the SD card.
We can only test this application in real device, so connect your device to the system through USB cable.
Right click on the project >> Run as >> Android application
Here is the final output:

Thanks
akm
www.cdacians.com

No comments:

Post a Comment