Saturday, November 8, 2014

Android: Camera

In this tutorial we will learn how to capture an image using Android Camera and how to pass this image from a Fragment back to Activity

Step: create a new Module "appSimpleCamera"

Step: design layout in "fragment_camera.xml"






























Step: Add ImageView and Fragment container to activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              tools:context=".MainActivity"
              tools:ignore="MergeRootFrame">
    <ImageView
            android:id="@+id/picturePreviewThumb"
            android:src="@android:drawable/ic_menu_gallery"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:contentDescription="Photo Capture"
            />
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:id="@+id/camera_fragment_container"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"/>
</LinearLayout>



Step: implement Fragment

package com.chicagoandroid.cit299.simplecamera;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
/**
 * Camera fragment containing a simple view.
 */
public class CameraFragment extends Fragment {
   ImageView takePhoto, picturePreview, savePhoto, cancel;
   /** picturePreviewThumb belongs to Activity, not this Fragment **/
   ImageView picturePreviewThumb;
   Bitmap capturedPhoto;
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View rootView = inflater.inflate(R.layout.fragment_camera, container, false);
      return rootView;
   }
   /**
    * Add your UI elements and their functionality here,
    * because in onCreateView(...) UI does not exist yet.
    * @param savedInstanceState
    */
   @Override
   public void onActivityCreated(@Nullable Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);
      // Inside fragment you have to use getView()..
      cancel = (ImageView) getView().findViewById(R.id.cancel);
      takePhoto = (ImageView) getView().findViewById(R.id.takePhoto);
      savePhoto = (ImageView) getView().findViewById(R.id.savePhoto);
      savePhoto.setVisibility(View.INVISIBLE);
      picturePreview = (ImageView) getView().findViewById(R.id.picturePreview);
      takePhoto.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            useCameraApp();
         }
      });
      savePhoto.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            passPhotoToActivity();
         }
      });
      cancel.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            clearScreen();
         }
      });
   }
   public void useCameraApp() {
      Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
      startActivityForResult(intent, 0);
   }
   @Override
   public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      Bundle bundle = data.getExtras();
      /** If user presses BACK BUTTON in Camera the bundle wil be null. **/
      if (bundle != null) {
         capturedPhoto = (Bitmap) bundle.get("data");
         picturePreview.setImageBitmap(capturedPhoto);
         savePhoto.setVisibility(View.VISIBLE);
      }
   }
   private void passPhotoToActivity() {
      picturePreviewThumb = (ImageView) getActivity().findViewById(R.id.picturePreviewThumb);
      picturePreviewThumb.setImageBitmap(capturedPhoto);
   }
   private void clearScreen() {
      /** Same as android:src="@android:drawable/ic_menu_gallery" **/
      picturePreview.setImageResource(android.R.drawable.ic_menu_gallery);
      savePhoto.setVisibility(View.INVISIBLE);
   }
}



Step: implement MainActivity


package com.chicagoandroid.cit299.simplecamera;
import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends ActionBarActivity {
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      addCameraFragment(savedInstanceState);
   }
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
   }
   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
      // Handle action bar item clicks here. The action bar will
      // automatically handle clicks on the Home/Up button, so long
      // as you specify a parent activity in AndroidManifest.xml.
      int id = item.getItemId();
      if (id == R.id.action_settings) {
         return true;
      }
      return super.onOptionsItemSelected(item);
   }
   /**
    * This method will be called in onCreate()
    * @param bundle savedInstanceState
    */
   private void addCameraFragment(Bundle bundle) {
      int containerId = R.id.camera_fragment_container;
      /**
       * Verify that your activity layout include a fragment container.
       * Depending on layout (size, orientation) and logic the container may not be present.
       */
      if (findViewById(containerId) == null) {
         return;
      }
      /** If restoring Activity do nothing to prevent creating existing Fragment. **/
      if (bundle != null) {
         return;
      }
      CameraFragment fragment = new CameraFragment();
      /** Pass in calling Intent's values, setting the Bundle in constructor is not recommended  **/
      // Bundle bundle = getIntent().getExtras(); //another way to get the bundle
      fragment.setArguments(bundle);
      getSupportFragmentManager().beginTransaction().add(containerId, fragment).commit();
   }
}