├── .classpath
├── .gitignore
├── .project
├── AndroidManifest.xml
├── README.md
├── ic_launcher-web.png
├── libs
└── android-support-v4.jar
├── proguard-project.txt
├── project.properties
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── drawable-xxhdpi
│ └── ic_launcher.png
├── layout
│ ├── activity_main.xml
│ └── activity_photo.xml
├── menu
│ └── main.xml
├── values-sw600dp
│ └── dimens.xml
├── values-sw720dp-land
│ └── dimens.xml
├── values-v11
│ └── styles.xml
├── values-v14
│ └── styles.xml
└── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── src
├── com
└── example
│ └── cameratester
│ └── MainActivity.java
└── org
└── calflora
└── experimental
└── CapturePhotoActivity.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 |
15 | # Local configuration file (sdk path, etc)
16 | local.properties
17 |
18 | # Intellij project files
19 | *.iml
20 | *.ipr
21 | *.iws
22 | .idea/
23 |
24 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | AndroidCameraTester
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Camera Tester
2 | ============
3 |
4 | Details different photo capture implementations on Android. Some work on certain devices, some don't.
5 |
6 | Please fork, fix issues you see with any of these, and most importantly consider adding examples of other strategies. Leveraging the camera in Android can be harder than it should be.
7 |
8 | **File URI**
9 | Lifted verbatim from http://developer.android.com/guide/topics/media/camera.html . This implementation attempts to pass the camera activity a URI for a file in external storage. This seems to return a null URI on some devices.
10 |
11 | **Content Resolver**
12 | Uses MediaStore.Images.Media.EXTERNAL_CONTENT_URI to generate a URI for the Camera activity. This seems to be stable across many devices, though it's not an implementation that is easily found online. Thanks to iNaturalist source code for kernal of source here.
13 |
14 | **Homegrown Camera**
15 | When all else fails, you can just implement your own camera. Not so feature rich, but it seems to work across many devices
16 |
--------------------------------------------------------------------------------
/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZavenArra/AndroidCameraTester/60eb29e0ba32495f9543aac8e66cc687d1c72c31/ic_launcher-web.png
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZavenArra/AndroidCameraTester/60eb29e0ba32495f9543aac8e66cc687d1c72c31/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZavenArra/AndroidCameraTester/60eb29e0ba32495f9543aac8e66cc687d1c72c31/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZavenArra/AndroidCameraTester/60eb29e0ba32495f9543aac8e66cc687d1c72c31/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZavenArra/AndroidCameraTester/60eb29e0ba32495f9543aac8e66cc687d1c72c31/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZavenArra/AndroidCameraTester/60eb29e0ba32495f9543aac8e66cc687d1c72c31/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
19 |
25 |
26 |
32 |
33 |
40 |
41 |
--------------------------------------------------------------------------------
/res/layout/activity_photo.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
11 |
12 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
--------------------------------------------------------------------------------
/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 | 50dp
7 |
8 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Camera Tester
5 | Settings
6 | Hello world!
7 |
8 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/src/com/example/cameratester/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.cameratester;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.text.SimpleDateFormat;
7 | import java.util.Date;
8 |
9 | import org.calflora.experimental.CapturePhotoActivity;
10 |
11 | import android.net.Uri;
12 | import android.os.Bundle;
13 | import android.os.Environment;
14 | import android.provider.MediaStore;
15 | import android.app.Activity;
16 | import android.content.ContentValues;
17 | import android.content.Intent;
18 | import android.database.Cursor;
19 | import android.graphics.Bitmap;
20 | import android.graphics.BitmapFactory;
21 | import android.util.Log;
22 | import android.view.Menu;
23 | import android.view.View;
24 | import android.view.View.OnClickListener;
25 | import android.widget.Button;
26 | import android.widget.ImageView;
27 | import android.widget.Toast;
28 |
29 | public class MainActivity extends Activity {
30 |
31 | private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_FILE_URI = 100;
32 | private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_CONTENT_RESOLVER = 101;
33 | private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_HOMEGROWN = 102;
34 |
35 |
36 | private Uri fileUri;
37 | private ImageView imageView;
38 |
39 | /** Create a file Uri for saving an image or video */
40 | private static Uri getOutputMediaFileUri(int type){
41 | return Uri.fromFile(getOutputMediaFile(type));
42 | }
43 |
44 | /** Create a File for saving an image or video */
45 | private static File getOutputMediaFile(int type){
46 | // To be safe, you should check that the SDCard is mounted
47 | // using Environment.getExternalStorageState() before doing this.
48 |
49 | File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
50 | Environment.DIRECTORY_PICTURES), "MyCameraApp");
51 | // This location works best if you want the created images to be shared
52 | // between applications and persist after your app has been uninstalled.
53 |
54 | // Create the storage directory if it does not exist
55 | if (! mediaStorageDir.exists()){
56 | if (! mediaStorageDir.mkdirs()){
57 | Log.d("MyCameraApp", "failed to create directory");
58 | return null;
59 | }
60 | }
61 |
62 | // Create a media file name
63 | String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
64 | File mediaFile;
65 | if (type == MEDIA_TYPE_IMAGE){
66 | mediaFile = new File(mediaStorageDir.getPath() + File.separator +
67 | "IMG_"+ timeStamp + ".jpg");
68 | } else if(type == MEDIA_TYPE_VIDEO) {
69 | mediaFile = new File(mediaStorageDir.getPath() + File.separator +
70 | "VID_"+ timeStamp + ".mp4");
71 | } else {
72 | return null;
73 | }
74 |
75 | return mediaFile;
76 | }
77 |
78 | //Content Resolver
79 | private Uri mPhotoUri;
80 | public static final int MEDIA_TYPE_IMAGE = 1;
81 | public static final int MEDIA_TYPE_VIDEO = 2;
82 |
83 |
84 |
85 | @Override
86 | protected void onCreate(Bundle savedInstanceState) {
87 | super.onCreate(savedInstanceState);
88 | setContentView(R.layout.activity_main);
89 |
90 | imageView = (ImageView) findViewById(R.id.imageView1);
91 |
92 |
93 | Button button = (Button) findViewById(R.id.button1);
94 | button.setOnClickListener(new OnClickListener(){
95 |
96 | @Override
97 | public void onClick(View v) {
98 | // Create Intent to take a picture and return control to the calling application
99 | // This is the strategy detailed by google at
100 | // http://developer.android.com/guide/topics/media/camera.html
101 | // This method doesn't seem to be reliable
102 | Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
103 |
104 | fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
105 | intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
106 |
107 | // start the image capture Intent
108 | startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_FILE_URI);
109 | }
110 | }
111 | );
112 |
113 | button = (Button) findViewById(R.id.button2);
114 | button.setOnClickListener(new OnClickListener(){
115 |
116 | @Override
117 | public void onClick(View v) {
118 | // Alternative strategy of generating a content URI using the MediaStore
119 | // This way seems to work very reliably
120 |
121 | mPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
122 | Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
123 | intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);
124 | startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_CONTENT_RESOLVER);
125 | }
126 | }
127 | );
128 |
129 |
130 | button = (Button) findViewById(R.id.button3);
131 | button.setOnClickListener(new OnClickListener(){
132 |
133 | @Override
134 | public void onClick(View v) {
135 | // Just use our own camera implementation
136 | // This works reliably, but doesn't always choose the best resolution for the camera
137 | // It also misses some other features
138 | // The capture photo activity could be improved to work just as well as the onboard camera activity
139 |
140 | Intent intent = new Intent("org.calflora.experimental.action.CAPTUREPHOTO");
141 | startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_HOMEGROWN);
142 |
143 | }
144 | }
145 | );
146 |
147 | }
148 |
149 | @Override
150 | public boolean onCreateOptionsMenu(Menu menu) {
151 | // Inflate the menu; this adds items to the action bar if it is present.
152 | getMenuInflater().inflate(R.menu.main, menu);
153 | return true;
154 | }
155 |
156 | @Override
157 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
158 | imageView.setImageBitmap(null);
159 |
160 | if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_FILE_URI) {
161 | if (resultCode == RESULT_OK) {
162 | // Image captured and saved to fileUri specified in the Intent
163 |
164 | // Docs at http://developer.android.com/guide/topics/media/camera.html
165 | // tell us that data should not be null, and getData() should be a fileUri
166 |
167 | if(data != null){
168 |
169 | Toast.makeText(this, "Image saved to:\n" +
170 | data.getData(), Toast.LENGTH_LONG).show();
171 | Uri fileUri = data.getData();
172 | if(fileUri == null){
173 | Toast.makeText(this, "fileUri is NULL", Toast.LENGTH_LONG).show();
174 | } else {
175 | try {
176 | Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), fileUri);
177 | imageView.setImageBitmap(bitmap);
178 | } catch (FileNotFoundException e) {
179 | Toast.makeText(this, "Failed to get bitmap from URI", Toast.LENGTH_LONG).show();
180 | e.printStackTrace();
181 | } catch (IOException e) {
182 | Toast.makeText(this, "Failed to get bitmap from URI", Toast.LENGTH_LONG).show();
183 | e.printStackTrace();
184 | }
185 |
186 | }
187 | } else {
188 |
189 | Toast.makeText(this, "Intent data is NULL", Toast.LENGTH_LONG).show();
190 | }
191 | } else if (resultCode == RESULT_CANCELED) {
192 | // User cancelled the image capture
193 | } else {
194 | // Image capture failed, advise user
195 | }
196 |
197 |
198 |
199 |
200 | } else if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_CONTENT_RESOLVER ) {
201 | if (resultCode == RESULT_OK) {
202 | // Image saved to a generated MediaStore.Images.Media.EXTERNAL_CONTENT_URI
203 | String[] projection = {
204 | MediaStore.MediaColumns._ID,
205 | MediaStore.Images.ImageColumns.ORIENTATION,
206 | MediaStore.Images.Media.DATA
207 | };
208 | Cursor c = getContentResolver().query(mPhotoUri, projection, null, null, null);
209 | c.moveToFirst();
210 | String photoFileName = c.getString(c.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
211 |
212 | Bitmap bitmap = BitmapFactory.decodeFile(photoFileName);
213 | imageView.setImageBitmap(bitmap);
214 |
215 | } else if (resultCode == RESULT_CANCELED) {
216 | // User cancelled the image capture
217 | } else {
218 | // Image capture failed, advise user
219 | }
220 |
221 | } else if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_HOMEGROWN ) {
222 | if (resultCode == RESULT_OK) {
223 | Bundle extras = data.getExtras();
224 | if(extras == null){
225 | Toast.makeText(this, "Error Capturing Images", Toast.LENGTH_LONG ).show();
226 | } else {
227 |
228 | String photoFileName = extras.getString(CapturePhotoActivity.PHOTO_FILE_NAME);
229 | Bitmap bitmap = BitmapFactory.decodeFile(photoFileName);
230 | imageView.setImageBitmap(bitmap);
231 | }
232 |
233 | } else if (resultCode == RESULT_CANCELED) {
234 | // User cancelled the image capture
235 | } else {
236 | // Image capture failed, advise user
237 | }
238 |
239 |
240 | }
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/src/org/calflora/experimental/CapturePhotoActivity.java:
--------------------------------------------------------------------------------
1 | package org.calflora.experimental;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 | import java.io.OutputStream;
8 | import java.util.Date;
9 | import java.util.List;
10 |
11 | import android.app.Activity;
12 | import android.content.Context;
13 | import android.content.Intent;
14 | import android.content.pm.ActivityInfo;
15 | import android.graphics.PixelFormat;
16 | import android.hardware.Camera;
17 | import android.os.Bundle;
18 | import android.util.Log;
19 | import android.view.Display;
20 | import android.view.KeyEvent;
21 | import android.view.Surface;
22 | import android.view.SurfaceHolder;
23 | import android.view.SurfaceView;
24 | import android.view.View;
25 | import android.view.Window;
26 | import android.view.WindowManager;
27 | import android.widget.Button;
28 | import android.widget.Toast;
29 |
30 | import com.example.cameratester.*;
31 |
32 | public class CapturePhotoActivity extends Activity implements SurfaceHolder.Callback
33 | {
34 | public static String PHOTO_FILE_NAME = "PHOTO_FILE_NAME";
35 |
36 | public static String getPhotoDirectory(Context context)
37 | {
38 | //return Environment.getExternalStorageDirectory().getPath() +"/cbo-up";
39 | return context.getExternalFilesDir(null).getPath() +"/cbo-up";
40 | }
41 | //private String PIC_DATA_PATH; // = "/sdcard/whatsinvasive";
42 | String fname;
43 | String TAG = "CapPhoto";
44 |
45 | Camera mCamera;
46 | boolean mPreviewRunning = false;
47 |
48 | private SurfaceView mSurfaceView;
49 | private SurfaceHolder mSurfaceHolder;
50 |
51 | @Override
52 | protected void onCreate(Bundle savedInstanceState) {
53 | super.onCreate(savedInstanceState);
54 |
55 |
56 | this.requestWindowFeature(Window.FEATURE_NO_TITLE);
57 | //this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
58 | this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
59 |
60 | Window window = getWindow();
61 | window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
62 | window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
63 |
64 | //Toast.makeText(this, "Take photo by pressing camera button or center directional pad. After you are done capturing photos, press back key.", Toast.LENGTH_LONG).show();
65 |
66 | window.setFormat(PixelFormat.TRANSLUCENT);
67 |
68 | setContentView(R.layout.activity_photo);
69 | mSurfaceView = (SurfaceView)findViewById(R.id.surface);
70 | Button button = (Button)findViewById(R.id.button);
71 | button.setOnClickListener(new View.OnClickListener()
72 | {
73 | public void onClick(View v)
74 | {
75 | if (mCamera != null)
76 | mCamera.autoFocus(mAutoFocusCallback);
77 | }
78 | });
79 |
80 | mSurfaceHolder = mSurfaceView.getHolder();
81 | mSurfaceHolder.addCallback(this);
82 |
83 | //Deprecated in 3.0
84 | // mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
85 | }
86 |
87 |
88 | Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
89 | public void onPictureTaken(byte[] data, Camera c) {
90 | Date now = new Date();
91 | long nowLong = now.getTime() / 9000;
92 | fname = getPhotoDirectory(CapturePhotoActivity.this)+"/"+nowLong+".jpg";
93 |
94 | String why = "";
95 | try {
96 |
97 | File ld = new File(getPhotoDirectory(CapturePhotoActivity.this));
98 | if (ld.exists()) {
99 | if (!ld.isDirectory()){
100 | CapturePhotoActivity.this.finish();
101 | }
102 | } else {
103 | ld.mkdir();
104 | }
105 |
106 | Log.d(TAG, "open output stream "+fname +" : " +data.length);
107 |
108 | OutputStream os = new FileOutputStream(fname);
109 | os.write(data,0,data.length);
110 | os.close();
111 | } catch (FileNotFoundException ex0) {
112 | why = ex0.toString();
113 | ex0.printStackTrace();
114 | } catch (IOException ex1) {
115 | why = ex1.toString();
116 | ex1.printStackTrace();
117 | }
118 |
119 | Log.d(TAG, "capture returns "+fname);
120 | File file = new File(fname); // keep this!
121 | Log.d(TAG, "exists? " +file.exists());
122 | if (!file.exists())
123 | Toast.makeText(getBaseContext(), "capture: file does not exist " + fname +" " +why, Toast.LENGTH_LONG);
124 |
125 | else {
126 |
127 | // setResult is used to send result back to the Activity that started this one.
128 | Intent intent = new Intent();
129 | intent.putExtra(CapturePhotoActivity.PHOTO_FILE_NAME, fname);
130 | //intent.putExtra("Tag", CapturePhoto.this.getIntent().getStringExtra("Tag"));
131 | //intent.putExtra("amount", CapturePhoto.this.getIntent().getStringExtra("amount")));
132 | setResult(RESULT_OK, intent);
133 | finish();
134 | }
135 | }
136 | };
137 |
138 | @Override
139 | public boolean onKeyDown(int keyCode, KeyEvent event)
140 | {
141 | if (keyCode == KeyEvent.KEYCODE_BACK) {
142 | CapturePhotoActivity.this.setResult(Activity.RESULT_CANCELED);
143 | CapturePhotoActivity.this.finish();
144 | return false;
145 | //return super.onKeyDown(keyCode, event);
146 | }
147 |
148 | if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_DPAD_CENTER)
149 | {
150 | mCamera.autoFocus(mAutoFocusCallback);
151 | return true;
152 | }
153 |
154 | return false;
155 | }
156 |
157 | Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback (){
158 |
159 | public void onAutoFocus(boolean success, Camera camera) {
160 | if (mCamera != null)
161 | {
162 | mCamera.takePicture(null, null, mPictureCallback);
163 | }
164 | }
165 |
166 | };
167 |
168 | @Override
169 | protected void onResume()
170 | {
171 | super.onResume();
172 | }
173 |
174 | @Override
175 | protected void onSaveInstanceState(Bundle outState)
176 | {
177 | super.onSaveInstanceState(outState);
178 | }
179 |
180 | @Override
181 | protected void onStop()
182 | {
183 | super.onStop();
184 | }
185 |
186 |
187 | public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
188 | {
189 | // XXX stopPreview() will crash if preview is not running
190 | if (mPreviewRunning) {
191 | mCamera.stopPreview();
192 | }
193 |
194 | // if this throws, use default:
195 | try
196 | {
197 | Camera.Parameters p = mCamera.getParameters();
198 |
199 | p.setPreviewSize(w, h);
200 | Log.d(TAG, "surface: get sizes:");
201 |
202 |
203 | List list = p.getSupportedPictureSizes();
204 | Camera.Size cs;
205 | Camera.Size best = null;
206 | if (list.size() > 0)
207 | {
208 | for (int i = 0; i < list.size(); i++)
209 | {
210 | cs = list.get(i);
211 | //Log.d(TAG, i+ " camera size: w: " +cs.width +" h: " + cs.height);
212 |
213 |
214 | //if (cs.width >= 1200 && cs.width <= 1024 && cs.height > 380 && cs.height <= 768)
215 | if (cs.height <= 1400) {
216 | if( best != null ){
217 | if(best.height > cs.height){
218 | continue;
219 | }
220 | }
221 |
222 | best = cs;
223 |
224 | }
225 |
226 | }
227 | }
228 | if (best != null)
229 | {
230 | Log.d(TAG, " USE size: " +best.width +" " + best.height);
231 | p.setPictureSize(best.width, best.height);
232 | }
233 | //p.setPictureSize(640, 480); // width height
234 | //p.setPictureSize(213, 350);
235 |
236 | Log.d(TAG, "surface: setParameters:");
237 |
238 | //This is meant to fix the rotation issues
239 | Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
240 |
241 | if(display.getRotation() == Surface.ROTATION_0)
242 | {
243 | p.setPreviewSize(h, w);
244 | mCamera.setDisplayOrientation(90);
245 | }
246 |
247 | if(display.getRotation() == Surface.ROTATION_90)
248 | {
249 | p.setPreviewSize(w, h);
250 | }
251 |
252 | if(display.getRotation() == Surface.ROTATION_180)
253 | {
254 | p.setPreviewSize(h, w);
255 | }
256 |
257 | if(display.getRotation() == Surface.ROTATION_270)
258 | {
259 | p.setPreviewSize(w, h);
260 | mCamera.setDisplayOrientation(180);
261 | }
262 |
263 |
264 |
265 | mCamera.setParameters(p);
266 | }
267 | catch (Throwable ex)
268 | {
269 | ex.printStackTrace();
270 | Log.d(TAG, "cannot set camera params! ex: " + ex);
271 | }
272 |
273 | try {
274 | mCamera.setPreviewDisplay(holder);
275 | } catch (IOException e) {
276 | e.printStackTrace();
277 | }
278 |
279 | Log.d(TAG, "surface: startPreview:");
280 | mCamera.startPreview();
281 | mPreviewRunning = true;
282 | }
283 |
284 | public void surfaceCreated(SurfaceHolder holder)
285 | {
286 | mCamera = Camera.open();
287 | if(mCamera==null) { // No backfacing camera
288 | mCamera = Camera.open(0);
289 | }
290 |
291 | try {
292 | mCamera.setPreviewDisplay(mSurfaceHolder);
293 | } catch (IOException ex) {
294 | mCamera.release();
295 | mCamera = null;
296 | // TODO: add more exception handling logic here
297 | Log.d(TAG, "surfaceCreated ex " + ex);
298 | }
299 | }
300 | public void surfaceDestroyed(SurfaceHolder holder)
301 | {
302 | mCamera.stopPreview();
303 | mPreviewRunning = false;
304 | mCamera.release();
305 | mCamera = null;
306 | }
307 | }
308 |
--------------------------------------------------------------------------------