Android 调用系统Camera 程序照相,获取照片
下面是我自己整理的源码,网络上好多不能够运行,或者有bug。
我在emulatorandroid2.1运行良好,源码注释一定程度能够自我解释
强烈推荐配合adblocatTake2:d*:s查看程序运行函数调用情况
对Activity生命周期不是很理解的,请先看我之前的一片文章
http://menuz.iteye.com/blog/1255320
<?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 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>
package com.busclient; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import android.app.Activity; import android.hardware.Camera; import android.hardware.Camera.PictureCallback; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class Take2 extends Activity implements SurfaceHolder.Callback { private final static String TAG = "Take2";; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private Camera mCam; private boolean hasStartPreview = false; private Button btnTakePicture; // Camera API: // Call release() to release the camera for use by other applications. // Applications should release the camera immediately in onPause() (and // re-open() it in onResume()). @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.takephoto); Log.d(TAG, "onCreate"); // 取得surfaceView的引用,surface在surfaceView中展现 // 当surfaceView可见时,surface会被创建,实现surfaceCreated进行特定操作 surfaceView = (SurfaceView) findViewById(R.id.surface_camera); btnTakePicture = (Button) findViewById(R.id.cameraButton); // 注册按钮实现拍照 btnTakePicture.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mCam != null) { // 调用mCam进行拍照 // param1 Camera.ShutterCallback // param2 Camera.PictureCallback raw 当原始图片数据获得时,会执行PictureCallback // param3 Camera.PictureCallback compressed 当压缩数据获得时,会执行PictureCallback mCam.takePicture(null, null, pictureCallBack); } } }); // 要操作surface,只有通过surfaceHolder surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } private PictureCallback pictureCallBack = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { if (mCam != null) { if (data != null) { File f = new File("/data/data/com.busclient/picture1.jpg"); FileOutputStream fout = null; try { if (!f.exists()) f.createNewFile(); fout = new FileOutputStream(f); fout.write(data); fout.close(); Log.d(TAG, "write success"); Thread.sleep(1500); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } finally { try { if (fout != null) { fout.close(); fout = null; } } catch (Exception e) { e.printStackTrace(); } } } finish(); } } }; // surface只能够由一个线程操作,一旦被操作,其他线程就无法操作surface @Override public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG, "surfaceCreated"); try { // 必须设置一个初始化的surfaceHolder,若没有surface(由holder操作surface), // 则camera无法启动预览 (就是一般打开照相机屏幕能够动态显示场景??描述的不够好) mCam.setPreviewDisplay(surfaceHolder); } catch (IOException e) { Log.d(TAG, "error"); mCam.release(); mCam = null; } } // 在surfaceCreated后调用,当surface发生变化也会触发该方法,这个方法 // 一般至少被调用一次 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d(TAG, "surfaceChanged"); // 调用startPreview使预览surface可以更新,拍照 // 必须启动预览,而startPreview必须在setPreviewDisplay(surfaceHolder)之后 if (mCam != null && hasStartPreview == false) { mCam.startPreview(); hasStartPreview = true; } } // 析构surface @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.d(TAG, "surfaceDestroyed"); // 活都被onPause抢去了 } @Override protected void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); } // onPause比surfaceDestroyed() 先调用 @Override protected void onPause() { Log.d(TAG, "onPause"); if (hasStartPreview) { mCam.stopPreview(); } mCam.release(); mCam = null; hasStartPreview = false; super.onPause(); } @Override protected void onRestart() { Log.d(TAG, "onRestart"); super.onRestart(); } @Override protected void onResume() { Log.d(TAG, "onResume"); if (mCam == null) mCam = Camera.open(); super.onResume(); } @Override protected void onStart() { Log.d(TAG, "onStart"); super.onStart(); } @Override protected void onStop() { Log.d(TAG, "onStop"); super.onStop(); } }
相关推荐
wangzhaotongalex 2020-09-22
古叶峰 2020-11-16
linmufeng 2020-09-08
xiaoxiaokeke 2020-07-28
好好学习天天 2020-07-21
83417807 2020-07-19
小方哥哥 2020-07-09
wbczyh 2020-07-05
pwc 2020-06-26
flowerCSDN 2020-06-16
Wonder的学习 2020-06-13
周小董 2020-06-10
luvhl 2020-06-08
nurvnurv 2020-06-05
Andrewjdw 2020-05-27
米虚 2020-05-19
专注前端开发 2020-03-01