您好,登錄后才能下訂單哦!
應用場景:
在Android開發(fā)過程中,有時需要調(diào)用手機自身設備的功能,本文側(cè)重攝像頭拍照功能的調(diào)用。
知識點介紹:
使用權(quán)限:調(diào)用手機自身設備功能(攝像頭拍照功能),應該確保已經(jīng)在AndroidManifest.xml中正確聲明了對攝像頭的使用及其它相關(guān)的feature。
<!--攝像頭權(quán)限 --> <uses-permission android:name="android.permission.CAMERA" /> <!--存儲權(quán)限 SD卡讀寫權(quán)限 --> <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" /> <!--視頻、錄音權(quán)限 請求音頻捕獲權(quán)限 --> <uses-permission android:name="android.permission.RECORD_VIDEO"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/>
Class類:
1、 SurfaceView
視圖(View)的繼承類,這個視圖里內(nèi)嵌了一個專門用于繪制的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪制位置。
2、 SurfaceHolder
SurfaceHolder是控制surface的一個抽象接口,你可以通過SurfaceHolder來控制surface的尺寸和格式,或者修改surface的像素,監(jiān)視surface的變化等等,SurfaceHolder是SurfaceView的典型接口。
3、 SurfaceHolder.Callback
用戶可以實現(xiàn)此接口接收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; } } } /** * 根據(jù)文件路徑獲取所需要文件,并將該文件封裝成Bitmap對象返回 * @param fileUrl * @return */ public static Bitmap getLoacalBitmap(String fileUrl) { try { FileInputStream fis = new FileInputStream(fileUrl); return BitmapFactory.decodeStream(fis); ///把流轉(zhuǎn)化為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; //拍照的回調(diào)接口 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 一個回調(diào)對象。 //用戶可以實現(xiàn)此接口接收surface變化的消息。當用在一個SurfaceView 中時, //它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之間有效。 //設置Callback的方法是SurfaceHolder.addCallback. //實現(xiàn)過程一般繼承SurfaceView并實現(xiàn)SurfaceHolder.Callback接口 surfaceHolder.addCallback(surfaceCallback); // 設置surface不需要自己的維護緩存區(qū) 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(){ // /* 按快門瞬間會執(zhí)行這里的代碼 */ // } // }; // 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當前的持有者的回調(diào)接口的實現(xiàn) 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實現(xiàn)攝像頭拍照功能
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。