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);
}
};
}
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;
}
}
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) {
}
}
}
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.