1. CompassActivity.java
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
public class CompassActivity extends Activity implements SensorEventListener,
Camera.AutoFocusCallback {
private CompassPreview compassPreview;
private DrawView drawView;
private SensorManager sensorManager;
private Sensor sensorAccelerometer;
private Sensor sensorMagneticField;
private TextView readingPitch, readingRoll;
private float[] valuesAccelerometer;
private float[] valuesMagneticField;
private float[] matrixR;
private float[] matrixI;
private float[] matrixValues;
private DecimalFormat decimalFormat;
private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
private ImageButton pictureBtn;
private Camera myCamera;
private byte[] pictureData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initWindow();
this.setContentView(R.layout.activity_camera);
initObject();
initSensor();
}
@Override
protected void onResume() {
super.onResume();
regListener();
initDormancy();
Load(Camera.CameraInfo.CAMERA_FACING_BACK);
}
@Override
protected void onPause() {
super.onPause();
unregListener();
releaseDormancy();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
public void Load(int camera_id) {
myCamera = getCameraInstance(camera_id);
if (myCamera != null) {
compassPreview.initCamera(myCamera);
}
}
public Camera getCameraInstance(int camera_id) {
Camera c = null;
try {
c = Camera.open(camera_id);// attempt to get a Camera instance
} catch (Exception e) {
Log.e("CompassActivity", e.getMessage());
Toast.makeText(this, "Camera is not release", Toast.LENGTH_SHORT)
.show();
}
return c; // returns null if camera is unavailable
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
for (int i = 0; i < 3; i++) {
valuesAccelerometer[i] = event.values[i];
}
break;
case Sensor.TYPE_MAGNETIC_FIELD:
for (int i = 0; i < 3; i++) {
valuesMagneticField[i] = event.values[i];
}
break;
}
boolean success = SensorManager.getRotationMatrix(matrixR, matrixI,
valuesAccelerometer, valuesMagneticField);
if (success) {
SensorManager.getOrientation(matrixR, matrixValues);
double azimuth = Math.toDegrees(-matrixValues[0]);
double pitch = Math.abs(Math.toDegrees(matrixValues[1]));
double roll = Math.abs(Math.toDegrees(matrixValues[2]));
drawView.updateRotate((float) azimuth, (float) pitch, (float) roll);
readingPitch
.setText("Pitch : " + decimalFormat.format(pitch) + "°");
readingRoll.setText("Roll : " + decimalFormat.format(roll) + "°");
}
}
public void initWindow() {
requestWindowFeature(Window.FEATURE_NO_TITLE); // 取消標題
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); // 全螢幕
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
public void initSensor() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorAccelerometer = sensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorMagneticField = sensorManager
.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
valuesAccelerometer = new float[3];
valuesMagneticField = new float[3];
matrixR = new float[9];
matrixI = new float[9];
matrixValues = new float[3];
}
public void regListener() {
sensorManager.registerListener(this, sensorAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, sensorMagneticField,
SensorManager.SENSOR_DELAY_NORMAL);
pictureBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
myCamera.autoFocus(CompassActivity.this);
}
});
}
public void unregListener() {
sensorManager.unregisterListener(this, sensorAccelerometer);
sensorManager.unregisterListener(this, sensorMagneticField);
}
public void initObject() {
compassPreview = (CompassPreview) this
.findViewById(R.id.compassPreview);
drawView = (DrawView) this.findViewById(R.id.drawView);
readingPitch = (TextView) this.findViewById(R.id.pitchText);
readingRoll = (TextView) this.findViewById(R.id.rollText);
pictureBtn = (ImageButton) this.findViewById(R.id.pictureBtn);
decimalFormat = new DecimalFormat("0.0");
powerManager = (PowerManager) this
.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, this
.getClass().getCanonicalName());
}
public void initDormancy() {
wakeLock.acquire();
}
public void releaseDormancy() {
wakeLock.release();
}
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
camera.takePicture(new Camera.ShutterCallback() {
@Override
public void onShutter() {
// TODO Auto-generated method stub
}
}, null, jpeg);
} else {
Toast.makeText(CompassActivity.this, "對焦失敗", Toast.LENGTH_SHORT)
.show();
}
}
Camera.PictureCallback jpeg = new Camera.PictureCallback() {
/** 拍照時,onPictureTaken()會自動被呼叫 */
public void onPictureTaken(byte[] imgData, Camera camera) {
if (imgData != null) {
pictureData = imgData;
new CompassActivity.MyPictureTask().execute(Environment
.getExternalStorageDirectory().getPath()
+ "/Camera_tools");
}
}
};
private class MyPictureTask extends AsyncTask<String, Integer, byte[]> {
private ProgressDialog progresslog;
private String showInformation;
@Override
protected void onPreExecute() {
super.onPreExecute();
progresslog = new ProgressDialog(CompassActivity.this, 1);
progresslog.setMessage("Loading Picture...");
progresslog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progresslog.show();
}
@Override
protected byte[] doInBackground(String... parameter) {
File path = new File(parameter[0]);
if (!path.exists()) {
path.mkdir();
}
Matrix matrix = new Matrix();
HashMap<Integer, Integer> cameraRotate = compassPreview
.getCameraDegree();
matrix.postRotate(cameraRotate
.get(Camera.CameraInfo.CAMERA_FACING_BACK));
try {
String fileName = getPath(path.getPath());
Bitmap picture = BitmapFactory.decodeByteArray(pictureData, 0,
pictureData.length);
FileOutputStream fOut = new FileOutputStream(fileName);
Bitmap bitmap = Bitmap.createBitmap(picture, 0, 0,
picture.getWidth(), picture.getHeight(), matrix, true);
if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut)) {
showInformation = "新增圖片至" + path.getPath() + "路徑";
}
fOut.flush();
fOut.close();
} catch (Exception io) {
Log.e("error", io.getMessage());
}
return null;
}
@Override
protected void onPostExecute(byte[] result) {
super.onPostExecute(result);
progresslog.dismiss();
progresslog = null;
Toast.makeText(CompassActivity.this, showInformation,
Toast.LENGTH_SHORT).show();
}
}
public String getPath(String path) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_kkmmss");
String date = dateFormat.format(new Date());
String photoFile = "Picture_" + date + ".png";
String fileName = path + File.separator + photoFile;
return fileName;
}
}
2. CompassPreview.java
import java.lang.reflect.Method;
import java.util.HashMap;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.os.Build;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CompassPreview extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera myCamera;
private Camera.CameraInfo cameraInfo;
public CompassPreview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void initCamera(Camera camera) {
myCamera = camera;
mHolder = this.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
try {
setCameraParameter(holder, format, width, height);
} catch (Exception e) {
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stopCamera();
}
private void stopCamera() {
myCamera.stopPreview();
myCamera.release();
myCamera = null;
}
private void setCameraParameter(SurfaceHolder holder, int format,
int width, int height) {
Camera.Parameters parameters = myCamera.getParameters();
HashMap<Integer, Integer> mapCameraInfo = getCameraDegree();
parameters.setPreviewSize(width, height);
if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
setDisplayOrientation(myCamera,
mapCameraInfo.get(cameraInfo.CAMERA_FACING_BACK));
} else {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
parameters.set("orientation", "portrait");
parameters.set("rotation",
mapCameraInfo.get(cameraInfo.CAMERA_FACING_BACK));
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
parameters.set("orientation", "landscape");
parameters.set("rotation",
mapCameraInfo.get(cameraInfo.CAMERA_FACING_BACK));
}
}
// List<Size> supportedPictureSizes = parameters
// .getSupportedPictureSizes();
//
// for (int i = 0; i < supportedPictureSizes.size(); i++) {
//
// Log.e("getSupportedPictureSizes(w, h)",
// supportedPictureSizes.get(i).width + ", "
// + supportedPictureSizes.get(i).height + ")");
// }
//
// List<Size> supportedPreviewSizes = parameters
// .getSupportedPreviewSizes();
// for (int i = 0; i < supportedPreviewSizes.size(); i++) {
//
// Log.e("getSupportedPreviewSizes(w, h)",
// supportedPreviewSizes.get(i).width + ", "
// + supportedPreviewSizes.get(i).height + ")");
// }
//
// parameters.setPictureSize(supportedPictureSizes.get(0).width,
// supportedPictureSizes.get(0).height);
try {
myCamera.setParameters(parameters);
myCamera.setPreviewDisplay(holder);
myCamera.startPreview();
} catch (Exception io) {
}
}
protected void setDisplayOrientation(Camera camera, int angle) {
Method downPolymorphic;
try {
downPolymorphic = camera.getClass().getMethod(
"setDisplayOrientation", new Class[] { int.class });
if (downPolymorphic != null)
downPolymorphic.invoke(camera, new Object[] { angle });
} catch (Exception io) {
}
}
public HashMap<Integer, Integer> getCameraDegree() {
HashMap<Integer, Integer> mapCameraInfo = new HashMap<Integer, Integer>();
int numberOfCameras = Camera.getNumberOfCameras();
cameraInfo = new Camera.CameraInfo();
for (int camera_id = 0; camera_id < numberOfCameras; camera_id++) {
Camera.getCameraInfo(camera_id, cameraInfo);
mapCameraInfo.put(camera_id, cameraInfo.orientation);
}
return mapCameraInfo;
}
}
3. DrawView.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceView;
public class DrawView extends SurfaceView {
private Bitmap compassBitmap;
private float[] apz;
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
compassBitmap = Bitmap.createBitmap(BitmapFactory.decodeResource(
getResources(), R.drawable.compass));
// draw method will not be called.
setWillNotDraw(false);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int centerComW = canvas.getWidth() / 2 - (compassBitmap.getWidth() / 2);
int centerComH = canvas.getHeight() / 2
- (compassBitmap.getHeight() / 2);
int centerCanW = canvas.getWidth() / 2;
int centerCanH = canvas.getHeight() / 2;
if (apz != null) {
if (!(apz[1] > 20 || apz[2] > 20)) {
canvas.rotate(apz[0], centerCanW, centerCanH);
canvas.drawBitmap(compassBitmap, centerComW, centerComH, null);
}
}
}
public void updateRotate(float... rotate) {
this.apz = rotate;
this.invalidate();
}
}
4. activity_camera.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.cameraactivity.CompassPreview
android:id="@+id/compassPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" >
</com.example.cameraactivity.CompassPreview>
<com.example.cameraactivity.DrawView
android:id="@+id/drawView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" >
</com.example.cameraactivity.DrawView>
<TextView
android:id="@+id/rollText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="50dp"
android:layout_marginLeft="27dp"
android:textColor="@android:color/white"
android:textSize="15sp" />
<TextView
android:id="@+id/pitchText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/rollText"
android:layout_alignParentBottom="true"
android:layout_marginBottom="22dp"
android:textColor="@android:color/white"
android:textSize="15sp" />
<ImageButton
android:id="@+id/pictureBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:background="@android:color/black"
android:src="@android:drawable/ic_menu_camera" />
</RelativeLayout>
5. AndroidManifest.xml(重點程式碼)
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
6. Compass Picture
沒有留言:
張貼留言