編輯:關於Android編程
本章節主要講述使用android.hardware.Camera類來實現自定義相機的流程,雖然在api21中該類已被廢棄,有了一套新的CameraDevice方法,但是為了向下兼容我們還是可以學習一下Camera1的使用。
如有錯誤或優化之處,歡迎留言指導。
首先介紹下如何判斷是否支持照相機功能,代碼如下:
private boolean checkCamera(Context context) { // 可修改參數來判斷設備是否支持ble等其他功能 if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { return true; // 支持Camera功能 } else { return false; } }
獲取一個Camera對象
private Camera getCamera() { Camera camera = null; try { camera = Camera.open(); } catch (Exception e) { Log.e(TAG, "getCamera: Camera.open failed!"); } return camera; }
我們通過SurfaceView來預覽照相機畫面,需要獲取SurfaceHolder並添加回調
mPreView = (SurfaceView) findViewById(R.id.preview); mHolder = mPreView.getHolder(); mHolder.addCallback(this); // 實現SurfaceHolder.Callback接口 mPreView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mCamera != null) { // 照相機自動對焦功能 mCamera.autoFocus(null); } } });
綁定Camera和SurfaceHolder,然後開始預覽畫面
private void setStartPreview(Camera camera, SurfaceHolder holder) { try { camera.setPreviewDisplay(holder); // 綁定Camera和SurfaceHolder camera.setDisplayOrientation(90); // 旋轉90度才是正常畫面 camera.startPreview(); } catch (IOException e) { Log.e(TAG, "setStartPreview: setPreviewDisplay error"); } }
在使用完相機後需要釋放相機資源,同時我們要注意把相機和活動的生命周期綁定,在onResume中獲取相機並預覽,在onPause中釋放相機資源,防止其他應用調用相機時出錯
private void releaseCamera() { if (mCamera != null) { mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); mCamera = null; } }
SurfaceHolder.Callback接口有create,change,destroy三個方法,我們在create中初始化,在change中預覽畫面,在destroy前釋放相機資源
@Override public void surfaceCreated(SurfaceHolder holder) { if (mCamera != null && mHolder != null) { setStartPreview(mCamera, mHolder); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (mCamera != null) { mCamera.stopPreview(); if (mHolder != null) { setStartPreview(mCamera, mHolder); } } } @Override public void surfaceDestroyed(SurfaceHolder holder) { releaseCamera(); }
最後就是點擊拍照並獲取圖片,這裡我們可以設置Camera.Parameters屬性作用於我們要拍攝的照片,調用tackPicture方法進行拍照
Camera.Parameters parameters = mCamera.getParameters(); parameters.setPictureFormat(ImageFormat.JPEG); // 相片保存的格式 parameters.setPictureSize(800, 400); // 相片保存的尺寸,因為是橫屏所以長>高 parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); // 自動對焦 mCamera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { if (success) { // 拍照 mCamera.takePicture(null, null, mPictureCallback); } } });
takePicture的第一個參數是快門的回調,後面兩個都是圖像數據的回調,通常我們只需要實現第三個存儲照片的回調就可以了
private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // 存儲的路徑及文件名 mFilePath = mFilePath + "/" + System.currentTimeMillis() + ".png"; File tempFile = new File(mFilePath); try { if (tempFile != null) { FileOutputStream fos = new FileOutputStream(tempFile); fos.write(data); fos.close(); Intent intent = new Intent(CameraActivity.this, PictureActivity.class); // 傳給下一個顯示照片的activity intent.putExtra("picPath", tempFile.getAbsolutePath()); startActivity(intent); finish(); } } catch (FileNotFoundException e) { Log.e(TAG, "onPictureTaken: " + e.getMessage()); } catch (IOException e) { Log.e(TAG, "onPictureTaken: " + e.getMessage() ); } } };
存儲完照片後,我們可以從傳遞的路徑獲取到圖片並顯示
mImageView = (ImageView) findViewById(R.id.iv_picture); mPath = getIntent().getStringExtra("picPath"); try { FileInputStream fis = new FileInputStream(new File(mPath)); Bitmap bitmap = BitmapFactory.decodeStream(fis); // 因為畫面預覽時是旋轉後顯示的,所以保存的圖片也需要旋轉90度 Matrix matrix = new Matrix(); matrix.setRotate(90); // 創建一個新的Bitmap bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); mImageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { Log.e(TAG, "onCreate: FileInputStream error"); }
Notification的使用大體步驟:1、 獲取狀態通知欄管理2、 實例化通知欄構造器3、 設置NotificationCompat.Builder4、 設置Pendi
SQLite是Android系統內置的數據庫,是一種輕量級的關系型數據庫,它運算速度快,占用資源少,非常適合在移動設備上使用。同時,它不僅支持標准的SQL語法,還遵循了數
Android中常常使用shape來定義控件的一些顯示屬性,今天看了一些shape的使用,對shape有了大體的了解,稍作總結:先看下面的代碼:<shape>
Android Studio 1.0 已經放出來了,以後的Android平台開發激昂逐步從Eclipse向Android Studio遷移,為了能不落伍我也特意從Goog