Working with Media




CS185c

Chris Pollett

Nov. 29, 2010

Outline

Announcements

Multimedia on Android

main.xml

AudioTestActivity.java

Playing Video

main.xml

VideoTestActivity.java

Quiz

Which of the following statements is true:

  1. Taps as we defined them last week can involve more than one finger.
  2. Both UIView and UIViewController are UIResponder's.
  3. To handle swipe events on Android you implement the SwipeEventListener interface.

Android's Camera

main.xml

CameraTest.java

package org.pollett;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore.MediaColumns;
import android.provider.MediaStore.Images.ImageColumns;
import android.provider.MediaStore.Images.Media;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraTest extends Activity implements SurfaceHolder.Callback {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        setContentView(R.layout.main);
        
        /*
           the surface holder is used to manage what is actually displayed 
           on the surface 
         */
        surfaceView = (SurfaceView)findViewById(R.id.surface);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);            
    }

    /**
       Adds menu to view the photos that have already been taken.
     */
    public boolean onCreateOptionsMenu(android.view.Menu menu)
    {
        MenuItem item = menu.add(0, 0, 0, "View Photos?");
        item.setOnMenuItemClickListener(
            new MenuItem.OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                    Intent intent = new Intent(Intent.ACTION_VIEW,
                            CameraTest.this.targetResource);
                    startActivity(intent);
                    return true;
                }
            }
        );
        return true;
    }

    /**
        Pushing the center button takes a picture,
        and sets up the callback for saving it.
     */
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        ImageCaptureCallback camDemo = null;
        if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            try {
                String filename= this.timeStampFormat.format(new Date());
                ContentValues values = new ContentValues();
                values.put(MediaColumns.TITLE, filename);
                values.put(ImageColumns.DESCRIPTION, "Image from emulator");
                Uri uri = getContentResolver().insert(
                        Media.EXTERNAL_CONTENT_URI, values);
                camDemo = new ImageCaptureCallback(
                        getContentResolver().openOutputStream(uri)
                        );
            } catch (Exception e) {
                
            }
        }
        if(keyCode == KeyEvent.KEYCODE_BACK) {
            return super.onKeyDown(keyCode, event);
        }
        if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            this.camera.takePicture(this.mShutterCallback, 
                    this.mPictureCallbackRaw, camDemo);
            return true;
        }
        return false;
    }
  
    /**
       Start the camera after the surface is created
     */
    public void surfaceCreated(SurfaceHolder holder) {
                this.camera = Camera.open();
    }
    
    /**
       Actually, display the camera data in the surface
     */
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        if(this.isPreviewRunning) {
            this.camera.stopPreview();
        }
        Camera.Parameters p = this.camera.getParameters();
        p.setPreviewSize(w, h);
        try {
            this.camera.setPreviewDisplay(holder);
            this.camera.startPreview();
            this.isPreviewRunning = true;
        } catch (Exception e) {
            
        }
    }


    /**
       Shut things down when surface goes away
     */
    public void surfaceDestroyed(SurfaceHolder holder) {
        this.camera.stopPreview();
        this.isPreviewRunning = false;
        this.camera.release();
    }

    //Handles raw data when picture taken
    Camera.PictureCallback mPictureCallbackRaw = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera c) {
            CameraTest.this.camera.startPreview();
        }
    };

    Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {
        public void onShutter() {
            //could be used to play a sound
        }
    };
   
    Camera camera;
    boolean isPreviewRunning = false;
    SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyyMMddHHmmssSS");
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    Uri targetResource = Media.EXTERNAL_CONTENT_URI;
    
    
}

ImageCaptureCallback.java

package org.pollett;

import java.io.OutputStream;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;

public class ImageCaptureCallback implements PictureCallback {
    
    public ImageCaptureCallback(OutputStream fileoutputStream)
    {
        this.fileoutputStream = fileoutputStream;
    }
    
    public void onPictureTaken(byte[] data, Camera camera) {
        try {
            this.fileoutputStream.write(data);
            this.fileoutputStream.flush();
            this.fileoutputStream.close();
            
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    OutputStream fileoutputStream;
}

Demo