SHOW:
|
|
- or go back to the newest paste.
1 | - | package com.blutechnologies.scancard; |
1 | + | |
2 | public class CameraActivity extends FragmentActivity implements SensorEventListener,ShutterButton.ShutterButtonListener,View.OnClickListener,KeyEvent.Callback | |
3 | - | import java.io.File; |
3 | + | |
4 | - | import java.io.FileNotFoundException; |
4 | + | |
5 | - | import java.io.FileOutputStream; |
5 | + | |
6 | - | import java.io.IOException; |
6 | + | |
7 | long sSensorCallTime; | |
8 | - | import android.annotation.TargetApi; |
8 | + | |
9 | - | import android.app.Activity; |
9 | + | |
10 | - | import android.content.Context; |
10 | + | |
11 | - | import android.content.Intent; |
11 | + | |
12 | - | import android.graphics.Bitmap; |
12 | + | |
13 | - | import android.graphics.BitmapFactory; |
13 | + | |
14 | - | import android.graphics.Matrix; |
14 | + | |
15 | - | import android.hardware.Camera; |
15 | + | |
16 | - | import android.hardware.Camera.AutoFocusCallback; |
16 | + | |
17 | - | import android.hardware.Camera.CameraInfo; |
17 | + | |
18 | - | import android.hardware.Camera.Parameters; |
18 | + | |
19 | - | import android.hardware.Camera.PictureCallback; |
19 | + | |
20 | - | import android.hardware.Sensor; |
20 | + | |
21 | - | import android.hardware.SensorEvent; |
21 | + | |
22 | - | import android.hardware.SensorEventListener; |
22 | + | |
23 | - | import android.hardware.SensorManager; |
23 | + | |
24 | - | import android.media.ExifInterface; |
24 | + | |
25 | - | import android.os.Build; |
25 | + | |
26 | - | import android.os.Bundle; |
26 | + | |
27 | - | import android.os.Debug; |
27 | + | |
28 | - | import android.os.Environment; |
28 | + | |
29 | - | import android.os.Handler; |
29 | + | |
30 | - | import android.os.Message; |
30 | + | |
31 | - | import android.support.v4.app.FragmentActivity; |
31 | + | |
32 | - | import android.util.Log; |
32 | + | |
33 | - | import android.view.KeyEvent; |
33 | + | |
34 | - | import android.view.OrientationEventListener; |
34 | + | |
35 | - | import android.view.Surface; |
35 | + | |
36 | - | import android.view.View; |
36 | + | |
37 | - | import android.view.Window; |
37 | + | |
38 | - | import android.view.WindowManager; |
38 | + | |
39 | - | import android.widget.FrameLayout; |
39 | + | |
40 | if(sFocusTime!=0 &&sClickTime==0) | |
41 | { | |
42 | sSensorCallTime=System.currentTimeMillis(); | |
43 | Log.d(TAG,"Sensor call time"+sSensorCallTime); | |
44 | } | |
45 | if(!isClicked){ | |
46 | float x=event.values[0]; | |
47 | float y=event.values[1]; | |
48 | float z=event.values[2]; | |
49 | if(mLastX==0) | |
50 | mLastX=x; | |
51 | if(mLastY==0) | |
52 | mLastY=y; | |
53 | if(mLastZ==0) | |
54 | mLastZ=z; | |
55 | ||
56 | float deltaX=x-mLastX; | |
57 | float deltaY=y-mLastY; | |
58 | float deltaZ=z-mLastZ; | |
59 | if(deltaX>2.5 || deltaY>2.5 || deltaZ>2.5) | |
60 | { | |
61 | if(mFocusState!=FOCUSING && mFocusState!=FOCUSING_SNAP_ON_FINISH) | |
62 | { | |
63 | mFocusState=FOCUS_NOT_STARTED; | |
64 | Log.d(TAG, "Focus called from accelerometer"); | |
65 | doFocus(true); | |
66 | } | |
67 | } | |
68 | mLastX=x; | |
69 | mLastY=y; | |
70 | mLastZ=z; | |
71 | } | |
72 | } | |
73 | - | private static final int FIRST_TIME_INIT = 1; |
73 | + | |
74 | - | private static final int CLEAR_SCREEN_DELAY = 2; |
74 | + | |
75 | - | |
75 | + | |
76 | - | |
76 | + | |
77 | - | private MyOrientationEventListener mOrientationListener; |
77 | + | |
78 | - | // The device orientation in degrees. Default is unknown. |
78 | + | |
79 | - | private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN; |
79 | + | |
80 | - | // The orientation compensation for icons and thumbnails. |
80 | + | |
81 | - | private int mOrientationCompensation = 0; |
81 | + | |
82 | - | |
82 | + | |
83 | - | private boolean mPreviewing; |
83 | + | |
84 | - | private boolean mPausing; |
84 | + | |
85 | - | private boolean mFirstTimeInitialized; |
85 | + | |
86 | - | |
86 | + | |
87 | btn_capture.setClickable(true); | |
88 | } | |
89 | ||
90 | @Override | |
91 | public void onResume() | |
92 | { | |
93 | super.onResume(); | |
94 | initializeCamera(); | |
95 | sensorManager.registerListener(this, sensor,SensorManager.SENSOR_DELAY_UI); | |
96 | } | |
97 | ||
98 | private void initializeCamera() | |
99 | { | |
100 | mCamera=null; | |
101 | Camera.CameraInfo info=new Camera.CameraInfo(); | |
102 | int cameraCount=Camera.getNumberOfCameras(); | |
103 | for(int cameraIndex=0;cameraIndex<cameraCount;cameraIndex++) | |
104 | { | |
105 | try | |
106 | { | |
107 | Camera.getCameraInfo(cameraIndex, info); | |
108 | if(cameraIndex==info.CAMERA_FACING_BACK) | |
109 | { | |
110 | mCamera=Camera.open(cameraIndex); | |
111 | } | |
112 | mPreview=new CameraPreview(this,mCamera); | |
113 | container.addView(mPreview); | |
114 | isPreviewShowing=true; | |
115 | } | |
116 | catch(Exception ex) | |
117 | { | |
118 | Log.d(TAG, "Could not open camera"); | |
119 | } | |
120 | } | |
121 | ||
122 | ||
123 | } | |
124 | ||
125 | private void autoFocus() | |
126 | { | |
127 | //Confused about the condition: | |
128 | if(mFocusState==FOCUS_NOT_STARTED && isPreviewShowing && mCameraStatus!=SNAPSHOT_IN_PROGRESS) | |
129 | { | |
130 | mFocusState=FOCUSING; | |
131 | mCamera.autoFocus(autoFocusCallback); | |
132 | } | |
133 | } | |
134 | ||
135 | private void cancelAutoFocus() | |
136 | { | |
137 | //Confused about the condition | |
138 | if(mCameraStatus==CAMERA_IDLE && (mFocusState==FOCUSING||mFocusState==FOCUS_SUCCESS||mFocusState==FOCUS_FAIL)) | |
139 | { | |
140 | mCamera.cancelAutoFocus(); | |
141 | } | |
142 | mFocusState=FOCUS_NOT_STARTED; | |
143 | } | |
144 | ||
145 | private void doSnap() | |
146 | { | |
147 | String mFocusMode=mCamera.getParameters().getFocusMode(); | |
148 | if(mFocusMode.equals(Parameters.FOCUS_MODE_INFINITY)||mFocusMode.equals(Parameters.FOCUS_MODE_EDOF)||mFocusMode.equals(mFocusMode.equals(Parameters.FOCUS_MODE_FIXED))||mFocusState==FOCUS_SUCCESS||mFocusState==FOCUS_FAIL||mFocusState==FOCUS_NOT_STARTED) | |
149 | - | if(mFirstTimeInitialized) |
149 | + | |
150 | - | initializeSecondTime(); |
150 | + | |
151 | //If the focus was not started,it will go through the focus states if the user holds on to the ShutterButton until the Camera focuses... | |
152 | - | initializeFirstTime(); |
152 | + | |
153 | mCameraStatus=SNAPSHOT_IN_PROGRESS; | |
154 | mCamera.takePicture(null, null, pictureCallback); | |
155 | } | |
156 | else if(mFocusState==FOCUSING) | |
157 | mFocusState=FOCUSING_SNAP_ON_FINISH; | |
158 | ||
159 | } | |
160 | - | try |
160 | + | |
161 | private void doFocus(boolean pressed) | |
162 | - | mCamera=Camera.open(); |
162 | + | |
163 | //Pressed is set to true,if ShutterButton is half-pressed | |
164 | - | catch(Exception ex) |
164 | + | |
165 | autoFocus(); | |
166 | - | Log.d(TAG, "Could not open camera"); |
166 | + | |
167 | cancelAutoFocus(); | |
168 | - | mPreview=new CameraPreview(this,mCamera); |
168 | + | |
169 | - | container.addView(mPreview); |
169 | + | |
170 | - | isPreviewShowing=true; |
170 | + | |
171 | public void onPause() | |
172 | { | |
173 | super.onPause(); | |
174 | sensorManager.unregisterListener(this); | |
175 | isPreviewShowing=false; | |
176 | killCamera(); | |
177 | container.removeAllViews(); | |
178 | } | |
179 | ||
180 | @Override | |
181 | public void onDestroy() | |
182 | { | |
183 | super.onDestroy(); | |
184 | } | |
185 | ||
186 | ||
187 | private void killCamera() | |
188 | { | |
189 | if(mCamera!=null) | |
190 | { | |
191 | mCamera.cancelAutoFocus(); | |
192 | mCamera.release(); | |
193 | mCamera=null; | |
194 | } | |
195 | - | int rotation=0; |
195 | + | |
196 | - | if (mOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) { |
196 | + | |
197 | - | CameraInfo info = new CameraInfo(); |
197 | + | |
198 | - | Camera.getCameraInfo(CameraInfo.CAMERA_FACING_BACK, info); |
198 | + | |
199 | - | if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { |
199 | + | |
200 | - | rotation = (info.orientation - mOrientation + 360) % 360; |
200 | + | |
201 | - | } else { // back-facing camera |
201 | + | |
202 | - | rotation = (info.orientation + mOrientation) % 360; |
202 | + | |
203 | - | } |
203 | + | |
204 | - | } |
204 | + | |
205 | - | Camera.Parameters params=mCamera.getParameters(); |
205 | + | |
206 | - | params.setRotation(rotation); |
206 | + | |
207 | - | mCamera.setParameters(params); |
207 | + | |
208 | else | |
209 | mFocusState=FOCUS_FAIL; | |
210 | doSnap(); | |
211 | } | |
212 | ||
213 | else if(mFocusState==FOCUSING) | |
214 | { | |
215 | if(success) | |
216 | mFocusState=FOCUS_SUCCESS; | |
217 | else | |
218 | mFocusState=FOCUS_FAIL; | |
219 | } | |
220 | ||
221 | else if(mFocusState==FOCUS_NOT_STARTED) | |
222 | { | |
223 | Log.d(TAG,"Focus not started,doing nothing"); | |
224 | } | |
225 | } | |
226 | ||
227 | }; | |
228 | ||
229 | PictureCallback pictureCallback=new PictureCallback() | |
230 | { | |
231 | ||
232 | @Override | |
233 | public void onPictureTaken(final byte[] data, Camera camera) { | |
234 | - | mOrientationListener.disable(); |
234 | + | |
235 | Log.d(TAG,"In picture callback"); | |
236 | mCameraStatus=CAMERA_IDLE; | |
237 | String path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath(); | |
238 | File dir=new File(path); | |
239 | if(!dir.exists()) | |
240 | dir.mkdirs(); | |
241 | String fileName="IMG_"+System.currentTimeMillis()+".jpg"; | |
242 | pathName=path+File.separator+fileName; | |
243 | new Thread() | |
244 | { | |
245 | public void run() | |
246 | { | |
247 | try { | |
248 | FileOutputStream fos=new FileOutputStream(pathName); | |
249 | - | mCamera.setPreviewCallback(null); |
249 | + | |
250 | - | mCamera.stopPreview(); |
250 | + | |
251 | } catch (FileNotFoundException e) { | |
252 | Log.e(TAG, "The output file could not be found",e); | |
253 | } catch (IOException e) { | |
254 | Log.e(TAG, "There was an exception writing from byte[] to file",e); | |
255 | } | |
256 | ||
257 | try { | |
258 | ExifInterface exif=new ExifInterface(pathName.toString()); | |
259 | int exifOrientation=exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL); | |
260 | Log.d(TAG,"Orient:"+exifOrientation); | |
261 | int rotate=0; | |
262 | switch(exifOrientation) | |
263 | { | |
264 | case ExifInterface.ORIENTATION_ROTATE_90: | |
265 | rotate=90; | |
266 | break; | |
267 | case ExifInterface.ORIENTATION_ROTATE_180: | |
268 | rotate=180; | |
269 | break; | |
270 | case ExifInterface.ORIENTATION_ROTATE_270: | |
271 | rotate=270; | |
272 | break; | |
273 | } | |
274 | Log.d(TAG,"Rotation:"+rotate); | |
275 | if(rotate!=0) | |
276 | { | |
277 | Bitmap bitmap=BitmapFactory.decodeFile(pathName); | |
278 | int w=bitmap.getWidth(); | |
279 | int h=bitmap.getHeight(); | |
280 | Matrix mtx=new Matrix(); | |
281 | mtx.preRotate(rotate); | |
282 | bitmap=Bitmap.createBitmap(bitmap, 0, 0,w,h,mtx,false); | |
283 | bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); | |
284 | FileOutputStream fos; | |
285 | try { | |
286 | fos = new FileOutputStream(pathName); | |
287 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); | |
288 | } catch (FileNotFoundException e) { | |
289 | Log.e(TAG, "Error saving rotated bitmap to file,e"); | |
290 | } | |
291 | } | |
292 | } | |
293 | catch(IOException e) { | |
294 | Log.e(TAG,"Rotate or coversion failed:"+e.toString()); | |
295 | } | |
296 | } | |
297 | }.start(); | |
298 | Intent intent=new Intent(getBaseContext(),ImagePreviewActivity.class); | |
299 | intent.putExtra("pathName", pathName); | |
300 | isPreviewShowing=false; | |
301 | startActivity(intent); | |
302 | } | |
303 | }; | |
304 | @Override | |
305 | public void onShutterButtonFocus(ShutterButton shutterButton, | |
306 | boolean pressed) { | |
307 | // TODO Auto-generated method stub | |
308 | sFocusTime=System.currentTimeMillis(); | |
309 | Log.d(TAG, "Shutter button focus called "+sFocusTime); | |
310 | switch(shutterButton.getId()) | |
311 | { | |
312 | case R.id.btn_capture: | |
313 | { | |
314 | isClicked=pressed; | |
315 | doFocus(pressed); | |
316 | break; | |
317 | } | |
318 | } | |
319 | ||
320 | } | |
321 | ||
322 | @Override | |
323 | public void onShutterButtonClick(ShutterButton shutterButton) { | |
324 | // TODO Auto-generated method stub | |
325 | Log.d(TAG, "Shutter button click called"); | |
326 | sClickTime=System.currentTimeMillis(); | |
327 | Log.d(TAG,"ShutterButtonClick time: "+sClickTime); | |
328 | Log.d(TAG,"Time taken to go to click"+((float)(sClickTime-sFocusTime)/1000)); | |
329 | switch(shutterButton.getId()) | |
330 | { | |
331 | case R.id.btn_capture: | |
332 | doSnap(); | |
333 | isClicked=false; | |
334 | break; | |
335 | } | |
336 | ||
337 | } | |
338 | ||
339 | @Override | |
340 | public void onClick(View v) { | |
341 | // TODO Auto-generated method stub | |
342 | //This assumes that the clicks the screen only if the focus has not been set... | |
343 | //This feature is useful in phones where accelerometer delay is unacceptable | |
344 | doFocus(true); | |
345 | } | |
346 | ||
347 | @Override | |
348 | public boolean onKeyDown(int keyCode,KeyEvent event) | |
349 | { | |
350 | switch(keyCode) | |
351 | { | |
352 | case KeyEvent.KEYCODE_BACK: | |
353 | startActivity(new Intent(this,MainActivity.class)); | |
354 | } | |
355 | return false; | |
356 | } | |
357 | ||
358 | ||
359 | } |