Tuesday, June 24, 2014

Using Camera in Your App

Android includes support for various cameras and camera features available on devices and allows you to capture pictures and videos for use in your applications. This tutorial shows a quick, simple approach to capture images and videos in your application.
1.   Considerations
You should consider a few questions about how your app intends to use the cameras feature before enabling your application to use them on Android devices.
ü  Camera Necessity - Is the camera so imperative for your application that you do not want it to be installed on a device that does not have a camera? If yes, you should declare the camera requirement in your manifest file.
ü  Storage - Are the media your application generates supposed to be visible only to your application or are they shared so that other applications such as Gallery or other media and social apps can use them? Do you need the pictures and videos to be available even when your application is uninstalled? View the Saving Media Files part to see how to implement these options.
2.  The Basics
The Android framework allows capturing images and videos through the Camera API or camera Intent. The relevant classes are:

  • Camera
This class is the primary API to control device cameras. This class is used to shoot pictures or videos when you are building a camera application.

  • SurfaceView
This class is used for presenting a live camera preview to the user.

  • MediaRecorder
This class is used for recording video from the camera.

  • Intent
An intent action type of MediaStore.ACTION_IMAGE_CAPTURE or MediaStore.ACTION_VIDEO_CAPTURE can be used to capture images or videos without directly using the Camera object.
3.   Manifest Declarations
Before initiating development on your application with the Camera API, make sure that your manifest file has the appropriate declarations to allow the use of camera hardware and other related features.
·   Camera Permission - Your application must solicit permission to use a device camera.
<uses-permission android:name="android.permission.CAMERA" />

    Note: If you are using the camera via an intent, your application need not request this permission

·  Camera Features - Your application must also declare use of camera features, for example:
<uses-feature android:name="android.hardware.camera" />
Adding camera features to your manifest file causes the app stores to prevent your application from being installed on devices that do not have a camera or do not support the camera features that you specify.
If your application can use a camera or camera feature for normal operation, but does not necessarily require it, you should specify this in the manifest by including the android:required attribute, and setting it to false:
<uses-feature android:name="android.hardware.camera" android:required="false" />

·  Storage Permission - If your application saves images or videos to the device's external storage (SD Card), you must also mention this in the manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

·  Audio Recording Permission - For recording audio along with video, your application must also request the audio capture permission.
<uses-permission android:name="android.permission.RECORD_AUDIO" />

·  Location Permission - If your application tags images with the device’s GPS location information, you must request location permission:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
4.   Using Existing Camera Apps
A speedy way to enable shooting pictures or videos in your application without a lot of additional code is to use an Intent to invoke an existing camera application. A camera intent requests an existing camera app to capture a picture or video clip and then returns the control back to your application. This section demonstrates how to capture an image or video using this technique.
The procedure for invoking a camera intent follows these general steps:
i.  Compose a Camera Intent - Create an Intent that requests an image or video, using one     of these intent types:
o  MediaStore.ACTION_IMAGE_CAPTURE - To request an image from an existing  camera application.
o    MediaStore.ACTION_VIDEO_CAPTURE - To request a video from an existing camera  application.
ii. Start the Camera Intent - Use the startActivityForResult() method to execute the camera intent. After you start the intent, the camera application user interface would appear on the device screen and the user can take a picture or a video.
iii.Receive the Intent Result - Set up an onActivityResult() method in your application to receive the callback and data from the camera intent. When the user finishes taking a picture or video or cancels the operation, the system calls this method.
5.   Image capture intent
Capturing images using a camera intent is a quick way to let your application take pictures with minimal coding. An image capture intent can include the following additional information:
·    MediaStore.EXTRA_OUTPUT - This setting requires a Uri object specifying a path and file name where you would like to save the picture. This setting is optional but strongly recommended. If you do not mention this value, the camera application would save the requested picture in the default location with a default name, as specified by the returned intent's Intent.getData() field.
The following example shows how to construct an image capture intent and execute it. The getOutputMediaFileUri() method in this example refers to the sample code shown in Saving Media Files.
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private Uri fileUri;

@Override
public void onCreate(Bundle savedInstanceState) {
   
super.onCreate(savedInstanceState);
    setContentView
(R.layout.main);

   
// create Intent to take a picture and return control to the calling application
   
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri
= getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
    intent
.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

   
// start the image capture Intent
    startActivityForResult
(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}

When the startActivityForResult() method is executed, users can see a camera application interface on their screen. After the user finishes taking a picture or cancels the operation, the user interface returns to your application, and you must intercept the onActivityResult() method to receive the result of the intent and continue your application’s smooth execution.
6.   Video capture intent
Capturing video using camera intent is a quick way to let your application take videos with minimal coding. A video capture intent can include the following additional information:
·   MediaStore.EXTRA_OUTPUT - This setting requires a Uri specifying a path and file name where you would like to save the video. This setting is optional but strongly recommended. If you do not specify this value, the Camera application saves the requested video in the default location with a default name, as specified in the returned intent's Intent.getData() field.
·   MediaStore.EXTRA_VIDEO_QUALITY - This value should be set to 0 for lowest quality and smallest file size, or 1 for highest quality and larger file size.
·  MediaStore.EXTRA_DURATION_LIMIT - This value can be used to limit the length of the video being captured, in seconds.
·  MediaStore.EXTRA_SIZE_LIMIT - This value can be used to limit the file size, in bytes, of the video being captured.
The following example shows how to construct a video capture intent and execute it. The getOutputMediaFileUri() method in this example refers to the sample code shown in Saving Media Files.
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;


private Uri fileUri;




@Override

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);




    //create new Intent

    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);



    fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);  // create a file to save the video

    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  // set the image file name



    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high




    // start the Video Capture Intent

    startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}

When the startActivityForResult() method is executed, users can see a camera application interface. After the user finishes taking a video or cancels the operation, the user interface returns to your application, and you must intercept the onActivityResult() method to receive the result of the intent and continue your application’s smooth execution.

7.   Receiving camera intent result

After finishing the construction and execution of an image or video camera intent, your application must be properly configured to receive the result of the intent. This section demonstrates how to intercept the callback from a camera intent so that your application can further process the captured image or video.
For receiving the result of an intent, you must override the onActivityResult() in the activity that started the intent. The following example shows how to override onActivityResult() to capture the result of the image camera intent or video camera intent examples shown above.
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100; 
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200; 
@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{     
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
      {         
          if (resultCode == RESULT_OK) 
          {         
                       // Image captured and saved to fileUri specified in the Intent             
                       Toast.makeText(this, "Image saved to:\n" +  data.getData(), Toast.LENGTH_LONG).show();
          } 
         else if (resultCode == RESULT_CANCELED) 
         {          
                     // User cancelled the image capture 
         } 
         else 
        { 
                    // Image capture failed, advise user    
         }    
     }    

if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) 
    {        
        if (resultCode == RESULT_OK) 
          {    
                     // Video captured and saved to fileUri specified in the Intent
                    Toast.makeText(this, "Video saved to:\n" +   data.getData(), Toast.LENGTH_LONG).show();  
          } 
       else if (resultCode == RESULT_CANCELED) 
         {          
                    // User cancelled the video capture         
         } 
      else 
        {         
                   // Video capture failed, advise user    
         }    
    } 
}

Once your activity receives a successful result, the captured image or video is available in the specified location for your application to access.

Code snippets taken from: 
http://developer.android.com/guide/topics/media/camera.html

Thursday, June 19, 2014

ListView

Want to design a vertically scrollable menu? ListView is the answer.
In Android, ListView lets you arrange components in a vertical scrolling list.
In this tutorial, we shall learn how to create two different types of ListView:
1.    Standard way to display components in ListView.
2.    Using custom array adapter to customize the item display.
1. Standard ListView example
In this example, we shall demonstrate how to display a list of programming languages with the help of ListView. This example is simple and easy to understand.
Step 1: Android Layout file
Create a new layout file in your project’s res folder.
File : res/layout/list_proglang.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
   
    <TextView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="25sp" >
    </TextView>
</LinearLayout>

Step 2: ListView
Create a Java file in your project’s src folder.
File : src/com.example.android/ListProglangActivity.java
package com.endeavour.listviewsample;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ListProglangActivity extends ListActivity{
        static final String[] Proglang = new String[] { "Java", "Objective-C", "C Sharp","JavaScript"};
@Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new ArrayAdapter<String> (this, R.layout.list_proglang, Proglang));
        ListView listView = getListView();
        listView.setTextFilterEnabled(true);
        listView.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
        int position, long id) {
        // When clicked, show a toast with the TextView text
            Toast.makeText(getApplicationContext(),
            ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
        }
        });
}
}
Step 3: Output
Running the project shall display the following result.

2. Using Custom ArrayAdapter

In this example, we shall demonstrate how to create 4 items in the ListView, and use a custom “ArrayAdapter” to display different images based on the “item name” in the list.
Step1: Images
Choose 4 images for the demonstration purpose.

Step 2: Android Layout file
File : res/layout/list_proglang.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="25sp" >
    </TextView>
</LinearLayout>
Step 3: Custom ArrayAdapter
Create a class that extends
 ArrayAdapter and customize the item display in the getView() method.
package com.endeavour.listviewsample;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
public class MobileArrayAdapter extends ArrayAdapter<String> 
{
        private final Context context;
        private final String[] values;
 
        public MobileArrayAdapter(Context context, String[] values)
        {
               super(context, R.layout.list_mobile, values);
               this.context = context;
               this.values = values;
        }
 
        @Override
        public View getView(int position, View convertView, ViewGroup parent) 
        {
               LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
               View rowView = inflater.inflate(R.layout.list_mobile, parent,false);
               TextView textView = (TextView) rowView.findViewById(R.id.label);
               ImageView imageView = (ImageView) rowView.findViewById(R.id.logo);
               textView.setText(values[position]);
               // Change image based on name
               String s = values[position];
               System.out.println(s);
               if (s.equals("C Sharp")) {
                                       imageView.setImageResource(R.drawable.windowsmobile_logo);
                               } 
               else if (s.equals("Objective-C")) {
                                      imageView.setImageResource(R.drawable.ios_logo);
                               } 
               else if (s.equals("Java")) {
                                      imageView.setImageResource(R.drawable.android_logo);
                               } 
               else {
                                      imageView.setImageResource(R.drawable.blackberry_logo);
                               }
               return rowView;
        }
}
Step 4: ListView
Create a ListView but use the above custom adapter to display the list.
package com.endeavour.listviewsample;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
 
public class ListMobileActivity extends ListActivity
{
        static final String[] ProgLang = new String[] { "Java", "Objective-C","C Sharp", "JavaScript"};
        @Override
        public void onCreate(Bundle savedInstanceState) 
        {
               super.onCreate(savedInstanceState);
               setListAdapter(new MobileArrayAdapter(this, ProgLang));
        }
        @Override
        protected void onListItemClick(ListView l, View v, int position, long id) 
        {
               //get selected items
               String selectedValue = (String) getListAdapter().getItem(position);
               Toast.makeText(this, selectedValue, Toast.LENGTH_SHORT).show();
               Intent i = new Intent(this, Temp.class);
               startActivity(i);
        }
}
Step 5: Output
Running the project shall display the following result.