Android 调用系统Camera 程序照相,获取照片
下面是我自己整理的源码,网络上好多不能够运行,或者有bug。
我在emulator android 2.1运行良好,源码注释一定程度能够自我解释
强烈推荐配合adb locat Take2:d *:s查看程序运行函数调用情况
对Activity生命周期不是很理解的,请先看我之前的一片文章
http://menuz.iteye.com/blog/1255320
Xml代码- 1.<?xml version="1.0" encoding="utf-8"?>
- 2.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- 3. android:orientation="vertical" android:layout_width="fill_parent"
- 4. android:layout_height="fill_parent">
- 5. <Button android:layout_width="fill_parent"
- 6. android:layout_height="wrap_content" android:id="@+id/cameraButton"
- 7. android:text="拍照" />
- 8.
- 9. <SurfaceView android:id="@+id/surface_camera"
- 10. android:layout_width="fill_parent" android:layout_height="10dip"
- 11. android:layout_weight="1">
- 12. </SurfaceView>
- 13.</LinearLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <Button android:layout_width="fill_parent"
- android:layout_height="wrap_content" android:id="@+id/cameraButton"
- android:text="拍照" />
- <SurfaceView android:id="@+id/surface_camera"
- android:layout_width="fill_parent" android:layout_height="10dip"
- android:layout_weight="1">
- </SurfaceView>
- </LinearLayout>
复制代码 Xml代码- 1.<?xml version="1.0" encoding="utf-8"?>
- 2.<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- 3. package="com.busclient"
- 4. android:versionCode="1"
- 5. android:versionName="1.0">
- 6. <uses-sdk android:minSdkVersion="7" />
- 7.
- 8. <uses-permission android:name="android.permission.CAMERA" /> <!-- 注意必须在application上面-->
- 9. <application android:icon="@drawable/icon" android:label="@string/app_name">
- 10. <uses-library android:name="com.google.android.maps" />
- 11. <activity android:name=".Take2"
- 12. android:label="@string/app_name">
- 13. <intent-filter>
- 14. <action android:name="android.intent.action.MAIN" />
- 15. <category android:name="android.intent.category.LAUNCHER" />
- 16. </intent-filter>
- 17. </activity>
- 18. </application>
- 19. <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/>
- 20. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- 21.</manifest>
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.busclient"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="7" />
-
- <uses-permission android:name="android.permission.CAMERA" /> <!-- 注意必须在application上面-->
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <uses-library android:name="com.google.android.maps" />
- <activity android:name=".Take2"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- </manifest>
复制代码 Java代码- 1.package com.busclient;
- 2.
- 3.import java.io.File;
- 4.import java.io.FileOutputStream;
- 5.import java.io.IOException;
- 6.
- 7.import android.app.Activity;
- 8.import android.hardware.Camera;
- 9.import android.hardware.Camera.PictureCallback;
- 10.import android.os.Bundle;
- 11.import android.util.Log;
- 12.import android.view.SurfaceHolder;
- 13.import android.view.SurfaceView;
- 14.import android.view.View;
- 15.import android.view.View.OnClickListener;
- 16.import android.widget.Button;
- 17.
- 18.public class Take2 extends Activity implements SurfaceHolder.Callback {
- 19. private final static String TAG = "Take2";;
- 20.
- 21. private SurfaceView surfaceView;
- 22.
- 23. private SurfaceHolder surfaceHolder;
- 24.
- 25. private Camera mCam;
- 26.
- 27. private boolean hasStartPreview = false;
- 28.
- 29. private Button btnTakePicture;
- 30.
- 31. // Camera API:
- 32. // Call release() to release the camera for use by other applications.
- 33. // Applications should release the camera immediately in onPause() (and
- 34. // re-open() it in onResume()).
- 35.
- 36. @Override
- 37. protected void onCreate(Bundle savedInstanceState) {
- 38. super.onCreate(savedInstanceState);
- 39. setContentView(R.layout.takephoto);
- 40. Log.d(TAG, "onCreate");
- 41.
- 42. // 取得surfaceView的引用,surface在surfaceView中展现
- 43. // 当surfaceView可见时,surface会被创建,实现surfaceCreated进行特定操作
- 44. surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
- 45. btnTakePicture = (Button) findViewById(R.id.cameraButton);
- 46. // 注册按钮实现拍照
- 47. btnTakePicture.setOnClickListener(new OnClickListener() {
- 48.
- 49. @Override
- 50. public void onClick(View v) {
- 51. if (mCam != null) {
- 52. // 调用mCam进行拍照
- 53. // param1 Camera.ShutterCallback
- 54. // param2 Camera.PictureCallback raw 当原始图片数据获得时,会执行PictureCallback
- 55. // param3 Camera.PictureCallback compressed 当压缩数据获得时,会执行PictureCallback
- 56. mCam.takePicture(null, null, pictureCallBack);
- 57. }
- 58. }
- 59.
- 60. });
- 61.
- 62. // 要操作surface,只有通过surfaceHolder
- 63. surfaceHolder = surfaceView.getHolder();
- 64. surfaceHolder.addCallback(this);
- 65. surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
- 66. }
- 67.
- 68. private PictureCallback pictureCallBack = new Camera.PictureCallback() {
- 69.
- 70. @Override
- 71. public void onPictureTaken(byte[] data, Camera camera) {
- 72. if (mCam != null) {
- 73. if (data != null) {
- 74. File f = new File("/data/data/com.busclient/picture1.jpg");
- 75. FileOutputStream fout = null;
- 76. try {
- 77. if (!f.exists())
- 78. f.createNewFile();
- 79. fout = new FileOutputStream(f);
- 80. fout.write(data);
- 81. fout.close();
- 82. Log.d(TAG, "write success");
- 83.
- 84. Thread.sleep(1500);
- 85. } catch (IOException e) {
- 86. e.printStackTrace();
- 87. } catch (InterruptedException e) {
- 88. e.printStackTrace();
- 89. } finally {
- 90. try {
- 91. if (fout != null) {
- 92. fout.close();
- 93. fout = null;
- 94. }
- 95. } catch (Exception e) {
- 96. e.printStackTrace();
- 97. }
- 98. }
- 99. }
- 100. finish();
- 101. }
- 102. }
- 103. };
- 104.
- 105. // surface只能够由一个线程操作,一旦被操作,其他线程就无法操作surface
- 106. @Override
- 107. public void surfaceCreated(SurfaceHolder holder) {
- 108. Log.d(TAG, "surfaceCreated");
- 109. try {
- 110. // 必须设置一个初始化的surfaceHolder,若没有surface(由holder操作surface),
- 111. // 则camera无法启动预览 (就是一般打开照相机屏幕能够动态显示场景??描述的不够好)
- 112. mCam.setPreviewDisplay(surfaceHolder);
- 113. } catch (IOException e) {
- 114. Log.d(TAG, "error");
- 115. mCam.release();
- 116. mCam = null;
- 117. }
- 118. }
- 119.
- 120. // 在surfaceCreated后调用,当surface发生变化也会触发该方法,这个方法
- 121. // 一般至少被调用一次
- 122. @Override
- 123. public void surfaceChanged(SurfaceHolder holder, int format, int width,
- 124. int height) {
- 125. Log.d(TAG, "surfaceChanged");
- 126. // 调用startPreview使预览surface可以更新,拍照
- 127. // 必须启动预览,而startPreview必须在setPreviewDisplay(surfaceHolder)之后
- 128. if (mCam != null && hasStartPreview == false) {
- 129.
- 130. mCam.startPreview();
- 131. hasStartPreview = true;
- 132. }
- 133. }
- 134.
- 135. // 析构surface
- 136. @Override
- 137. public void surfaceDestroyed(SurfaceHolder holder) {
- 138. Log.d(TAG, "surfaceDestroyed");
- 139. // 活都被onPause抢去了
- 140. }
- 141.
- 142. @Override
- 143. protected void onDestroy() {
- 144. Log.d(TAG, "onDestroy");
- 145. super.onDestroy();
- 146. }
- 147.
- 148. // onPause比surfaceDestroyed() 先调用
- 149. @Override
- 150. protected void onPause() {
- 151. Log.d(TAG, "onPause");
- 152. if (hasStartPreview) {
- 153. mCam.stopPreview();
- 154. }
- 155. mCam.release();
- 156. mCam = null;
- 157. hasStartPreview = false;
- 158. super.onPause();
- 159. }
- 160.
- 161. @Override
- 162. protected void onRestart() {
- 163. Log.d(TAG, "onRestart");
- 164. super.onRestart();
- 165. }
- 166.
- 167. @Override
- 168. protected void onResume() {
- 169. Log.d(TAG, "onResume");
- 170. if (mCam == null)
- 171. mCam = Camera.open();
- 172. super.onResume();
- 173. }
- 174.
- 175. @Override
- 176. protected void onStart() {
- 177. Log.d(TAG, "onStart");
- 178. super.onStart();
- 179. }
- 180.
- 181. @Override
- 182. protected void onStop() {
- 183. Log.d(TAG, "onStop");
- 184. super.onStop();
- 185. }
- 186.
- 187.}
复制代码 |