應用場景:
在Android開發過程中,有時需要調用手機自身設備的功能,本文側重攝像頭拍照功能的調用。
知識點介紹:
使用權限:調用手機自身設備功能(攝像頭拍照功能),應該確保已經在AndroidManifest.xml中正確聲明了對攝像頭的使用及其它相關的feature。
<!--攝像頭權限 --> <uses-permission android:name="android.permission.CAMERA" /> <!--存儲權限 SD卡讀寫權限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!--Camera Feature 聲明對camera feature的使用 --> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" /> <!--視頻、錄音權限 請求音頻捕獲權限 --> <uses-permission android:name="android.permission.RECORD_VIDEO"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/>
Class類:
	1、 SurfaceView
	視圖(View)的繼承類,這個視圖里內嵌了一個專門用于繪制的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪制位置。
	2、 SurfaceHolder
	SurfaceHolder是控制surface的一個抽象接口,你可以通過SurfaceHolder來控制surface的尺寸和格式,或者修改surface的像素,監視surface的變化等等,SurfaceHolder是SurfaceView的典型接口。
	3、 SurfaceHolder.Callback
	用戶可以實現此接口接收surface變化的消息。當用在一個SurfaceView 中時,  它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之間有效。設置Callback的方法是SurfaceHolder.addCallback。
使用方式:
第一步:新建一個Android項目CameraTest,包含兩個Activity: MainActivity、CameraActivity。
第二步:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:background="#FFFFFF" android:layout_height="match_parent" tools:context=".MainActivity" > <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent"> <ImageView android:id="@+id/main_image" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" android:layout_width="match_parent"/> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:orientation="horizontal"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/main_camera" android:text="拍照"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="退出" android:id="@+id/main_quit"/> </LinearLayout> </RelativeLayout>
MainActivity.java
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException;  import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView;  public class MainActivity extends Activity {   private Button cameraButton; //拍照按鈕  private Button quitButton; //退出按鈕  private ImageView imageView; //圖片顯示   @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  initViews();  }   private void initViews() {  imageView = (ImageView) findViewById(R.id.main_image); // 從本地取圖片(在sdcard中獲取文件)  Bitmap bitmap = getLoacalBitmap("/sdcard/mhc.jpg");  Log.e("msgTag", new File("/sdcard/mhc.jpg").exists()+"==========");  imageView .setImageBitmap(bitmap); //設置Bitmap  cameraButton = (Button) findViewById(R.id.main_camera);  quitButton = (Button) findViewById(R.id.main_quit);  MainOnClickListener mainOnClickListener = new MainOnClickListener();  cameraButton.setOnClickListener(mainOnClickListener);  quitButton.setOnClickListener(mainOnClickListener);  }   private class MainOnClickListener implements OnClickListener{   @Override  public void onClick(View v) {  switch (v.getId()) {  case R.id.main_camera:  startActivity(new Intent(MainActivity.this, CameraActivity.class));  break;  case R.id.main_quit:  MainActivity.this.finish();  break;  default:  break;  }  }  }   /**  * 根據文件路徑獲取所需要文件,并將該文件封裝成Bitmap對象返回  * @param fileUrl  * @return  */  public static Bitmap getLoacalBitmap(String fileUrl) {  try {  FileInputStream fis = new FileInputStream(fileUrl);  return BitmapFactory.decodeStream(fis); ///把流轉化為Bitmap圖片  } catch (FileNotFoundException e) {  e.printStackTrace();  return null;  }  } } activity_camera.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFF" tools:context=".CameraActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" > <SurfaceView android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_vertical|center_horizontal" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> <Button android:id="@+id/camera_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="拍照" /> </LinearLayout> </RelativeLayout>
CameraActivity.java
import java.io.File; import java.io.FileOutputStream; import java.io.IOException;  import android.graphics.ImageFormat; import android.hardware.Camera; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; 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 CameraActivity extends Activity {  private String tag ="CameraActivity";  private SurfaceView surfaceView;  //Surface的控制器  private SurfaceHolder surfaceHolder;  private Camera camera;  private Button saveButton;  //拍照的回調接口  private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {  public void onPictureTaken(byte[] data, Camera camera) {  new SavePictureTask().execute(data);  camera.startPreview();  }  };   @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_camera);  initViews();  }   private void initViews() {  saveButton = (Button) findViewById(R.id.camera_save);  surfaceView = (SurfaceView) findViewById(R.id.camera_preview);  surfaceHolder = surfaceView.getHolder();  // 給SurfaceView當前的持有者 SurfaceHolder 一個回調對象。  //用戶可以實現此接口接收surface變化的消息。當用在一個SurfaceView 中時,  //它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之間有效。  //設置Callback的方法是SurfaceHolder.addCallback.  //實現過程一般繼承SurfaceView并實現SurfaceHolder.Callback接口  surfaceHolder.addCallback(surfaceCallback);  // 設置surface不需要自己的維護緩存區  surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  saveButton.setOnClickListener(new OnClickListener() {   @Override  public void onClick(View v) {  camera.takePicture(null, null, pictureCallback); // Camera.takePicture(shutterCallback,rawCallback,pictureCallback ); // private ShutterCallback shutterCallback = new ShutterCallback(){ //  public void onShutter(){ //  /* 按快門瞬間會執行這里的代碼 */ //  } //  }; // private PictureCallback rawCallback = new PictureCallback(){ //  public void onPictureTaken(byte[] _data, Camera _camera){ //  /* 如需要處理 raw 則在這里 寫代碼 */ //  } //  }; //  //當拍照后 存儲JPG文件到 sd卡 //  PictureCallback pictureCallback=new PictureCallback(){ //  public void onPictureTaken(byte[] data,Camera camera) { //  FileOutputStream outSteam=null; //  try{ //  SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmss"); //  String times=format.format((new Date())); //  outSteam=new FileOutputStream("/sdcard/"+times+"mhc.jpg"); //  outSteam.write(data); //  outSteam.close(); //  }catch(FileNotFoundException e){ //  Log.d("Camera", "row"); //  } catch (IOException e) { //  e.printStackTrace(); //  } //  }; //  };  }  });  }    //SurfaceView當前的持有者的回調接口的實現  SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {   @Override  public void surfaceCreated(SurfaceHolder holder) {  camera = Camera.open();  Log.e(tag, "攝像頭Open完成");  try {  camera.setPreviewDisplay(holder);  } catch (IOException e) {  camera.release();  camera = null;  }  }   @Override  public void surfaceChanged(SurfaceHolder holder, int format, int width,  int height) {  Camera.Parameters parameters = camera.getParameters();  parameters.setPictureFormat(ImageFormat.JPEG);  camera.setDisplayOrientation(0);  camera.setParameters(parameters);  camera.startPreview();  }   @Override  public void surfaceDestroyed(SurfaceHolder holder) {  camera.stopPreview();  camera.release();  camera = null;  }  };   class SavePictureTask extends AsyncTask<byte[], String, String> {  @Override  protected String doInBackground(byte[]... params) {  File picture = new File("/sdcard/mhc.jpg");  try {  FileOutputStream fos = new FileOutputStream(picture.getPath());  fos.write(params[0]);  fos.close();  } catch (Exception e) {  e.printStackTrace();  }  Log.e(tag, "照片保存完成");  CameraActivity.this.finish();  return null;  }  } } 下載地址:Android實現攝像頭拍照功能
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答