//ToDo

Add photos and instructions...


Once you have a head-mount for your cell phone, you'll never understand how you got by without one.

Code:

Hatv2

Initiates the acitivity and manages the timer.

				
package com.android.hat;

import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.util.Log;
import android.widget.Button;
import android.widget.FrameLayout;

public class Hatv2 extends Activity {
	private static final String TAG = "Hat";
	protected PowerManager.WakeLock mWakeLock;
	protected Camera camera;
	protected Preview preview;
	protected Button buttonClick;

	private final Handler mHandler = new Handler();

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

		// create Preivew and add to the view
		preview = new Preview(this);
		((FrameLayout) findViewById(R.id.preview)).addView(preview);
		
		//set up system based timer
		mHandler.removeCallbacks(mUpdateTimeTask);
		mHandler.postDelayed(mUpdateTimeTask, 10000);
		Log.d(TAG, "created Hat");
		
		// prevent cpu from shutting down
		final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        this.mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
        this.mWakeLock.acquire();
	}

	@Override
	public void onStop() {
		mHandler.removeCallbacks(mUpdateTimeTask);
		Log.d(TAG, "timer task stopped");
		this.mWakeLock.release();
	}
	
	@Override
	public void onRestart() {
		//set up system based timer
		mHandler.removeCallbacks(mUpdateTimeTask);
		mHandler.postDelayed(mUpdateTimeTask, 10000);
		Log.d(TAG, "restarted activity");
		
		// prevent cpu from shutting down
		final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        this.mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
        this.mWakeLock.acquire();
	}

	private Runnable mUpdateTimeTask = new Runnable() {
		public void run() {
			preview.takePhoto();
			Log.d(TAG, "timer task updated");
			mHandler.postDelayed(this, 5000);
		}
	};
}

				

Preview

Creates the necessary surface to initiate a camera preview, then takes a photo and saves it onto the sd card.

        
package com.android.hat;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.graphics.PixelFormat;

public class Preview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback, Camera.ShutterCallback, Camera.PictureCallback{
	private static final String TAG = "Hat";
	SurfaceHolder holder;
	Camera camera;

	Preview(Context context) {
		super(context);
		// Install a SurfaceHolder.Callback so we get notified when the
		// underlying surface is created and destroyed.
		holder = getHolder();
		holder.addCallback(this);
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		Log.d(TAG, "Created");
	}

	// Called once the holder is ready
	public void surfaceCreated(SurfaceHolder holder) {
		// The Surface has been created, acquire the camera and tell it where
		// to draw.
		camera = Camera.open();
		try {
			camera.setPreviewDisplay(holder);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		// Surface will be destroyed when we return, so stop the preview.
		// Because the CameraDevice object is not a shared resource, it's very
		// important to release it when the activity is paused.
		camera.release();
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
		// Now that the size is known, set up the camera parameters and begin
		// the preview.
		Camera.Parameters params = camera.getParameters();
		List sizes = params.getSupportedPictureSizes();
		Size optimalSize = getOptimalPreviewSize(sizes, w, h);
		params.setPreviewSize(optimalSize.width, optimalSize.height);
		params.setPictureSize(optimalSize.width, optimalSize.height);
		params.setPictureFormat(PixelFormat.JPEG);
		params.setJpegQuality(50);
		params.setSceneMode(Camera.Parameters.SCENE_MODE_SPORTS);
		params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
		params.setRotation(0);
		camera.setParameters(params);
		camera.startPreview();
		Log.d(TAG, "1st Preview called using: " + params.flatten());
	}
	
	public void takePhoto() {
		camera.startPreview();
		camera.setOneShotPreviewCallback(this);
	}

	public void onPreviewFrame(byte[] _data, Camera _camera) {
		camera.takePicture(this, null, this);
		Log.d(TAG, "Photo taken at: " + System.currentTimeMillis());
	}


	/** Handles data for jpeg picture */
	public void onPictureTaken(byte[] data, Camera camera) {
		String fileName = String.format("/sdcard/sd/hat/%d.jpg", System.currentTimeMillis());
		FileOutputStream outStream = null;
		try {
			outStream = new FileOutputStream(fileName);
			outStream.write(data);
			outStream.close();
			Log.d(TAG, "picture saved - wrote bytes: " + data.length);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		new Uploader(String.format("%d.jpg", System.currentTimeMillis()), fileName);
		Log.v(TAG, "Took Picture: " + fileName + "is like this big: " + data.length);
	}

	@Override
	public void onShutter() {
		Log.d(TAG, "Shutter'd");
	}
	
	private Size getOptimalPreviewSize(List sizes, int w, int h) {
        if (sizes == null) return null;

        Size optimalSize = null;
        int targetWidth = 800;

        // Try to find an size match 
        for (Size size : sizes) {
            if(size.width > targetWidth){
                optimalSize = size;
            	}
            }
		Log.v(TAG, "this is the size: " + optimalSize.width);
        return optimalSize;
        }

}		
				

Uploader

Prepares jpegs, then uploads them.

 

package com.android.hat;

import java.io.File;
import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;

import android.util.Log;

public class Uploader extends Thread {
	private static final String TAG = "Preview";
	private String localFilePath;
	private String fileNameOnServer;

	public Uploader(String _fileNameOnServer, String _localFilePath) {
		localFilePath = _localFilePath;
		fileNameOnServer = _fileNameOnServer;
		start();
		Log.d(TAG, "Created");
	}

	public void run() {
		String urlString = "http://spencermccormick.com/_php/marathon_jpg.php";
		
		HttpClient httpclient = new DefaultHttpClient();
		HttpPost httppost = new HttpPost(urlString);
		Log.d(TAG, "Uploading " + localFilePath + " to " + urlString);

		try {
			MultipartEntity entity = new MultipartEntity();
			entity.addPart("uploadedfilename", new StringBody(fileNameOnServer));
			entity.addPart("uploadedfile", new FileBody(new File(localFilePath)));
			httppost.setEntity(entity);
			httpclient.execute(httppost);
		} catch (ClientProtocolException e) {
		} catch (IOException e) {
		}
	}
}

				

Android Manifest

You have to have the following permissions.

				

<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.PERSISTENT_ACTIVITY"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK" />




 		
				

Spencer McCormick lives in New York City, is 24 years old, and is super interested in the big questions: meaning of life, choice and self. His five year plan is to have a comprehensive answer to each.

The goal of this project was to learn Android development and complete a marathon. I would like to finish in under three hours.

:==> home page <==: