Sunday, November 13, 2016

相機預覽與方向性



在Android默認情況,當“屏幕方向”或“鍵盤顯示隱藏”變化時都會銷毀當前Activity,創建新的Activity。如果不希望重新創建Activity實例,可以在AndroidManifest.xml中配置
Activity:
<activity android:name=".MainActivity" android:configChanges="keyboardHidden|orientation" >
這樣就不會銷毀重建了在配置了這個屬性後,android:configChanges 屬性就會捕獲“屏幕方向”和“鍵盤顯示隱藏”變化,當捕獲到這些變化後會調用Activity的onConfigurationChanged()方法。

我在手機上調試發現橫豎屏切換時,並沒有執行onConfigurationChanged()方法,但是Activity卻執行了銷毀重建的過程這是為什麼呢?這是因為版本的問題上面的配置只在android4.o之前的版本起作用,在android 4.0 以上不起作用,必須要加上screenSize,也就是說android 4.0以後的版本必須這樣配置android:configChanges=" keyboardHidden|orientation|screenSize"

下面我們結合實例說orientation和onConfigurationChanaged方法

代碼:
          <activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="landscape"
>

AndroidManifest.xml 中加上 permission 和 feature
        

<uses-permission android:name="android.permission.CAMERA">
<uses-feature android:name="android.hardware.camera">
<uses-feature android:name="android.hardware.camera.autofocus">

另外使用Camera API拍照或攝像,都需要用到預覽,預覽就要用到SurfaceView,為此Activity的佈局中必須有SurfaceView。
   
<SurfaceView
android:id="@+id/surfaceView1"
android:layout_width="320px"
android:layout_height="240px">
</SurfaceView>

code:
   
package com.example.cheng.camera_for_led;

import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
import static android.hardware.Camera.getNumberOfCameras;

public class MainActivity extends Activity implements SurfaceHolder.Callback,Camera.PreviewCallback {
private static final String TAG = "My_CAMERA";
Camera myCamera;
SurfaceView previewSurfaceView;
SurfaceHolder previewSurfaceHolder;
boolean previewing = false;

/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFormat(PixelFormat.UNKNOWN);

previewSurfaceView = (SurfaceView) findViewById(R.id.previewsurface);
previewSurfaceHolder = previewSurfaceView.getHolder();// 绑定SurfaceView,取得SurfaceHolder对象
previewSurfaceHolder.addCallback(this);//SurfaceHolder加入回调接口
previewSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 設置顯示器類型,setType必须设置
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub

if (previewing) {
myCamera.stopPreview();
previewing = false;
}
try {
myCamera.setPreviewDisplay(arg0);
//Camera.Parameters parameters = myCamera.getParameters();
Log.d(TAG, "ttttt");
myCamera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
myCamera = Camera.open();//开启摄像头(2.3版本后支持多摄像头,需传入参数)
int a = getNumberOfCameras();
Log.d(TAG+" number = ", String.valueOf(a));
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
myCamera.stopPreview();
myCamera.release();
myCamera = null;
previewing = false;
}

@Override
public void onPreviewFrame(byte[] data, Camera camera) {

}
//当指定了android:configChanges="orientation"后,方向改变时onConfigurationChanged被调用,并且activity不再销毁重建
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
switch (newConfig.orientation) {
case Configuration.ORIENTATION_PORTRAIT://竖屏
Log.i(TAG,"竖屏");
// setContentView(R.layout.activity_main);
myCamera.setDisplayOrientation(0); // 在2.2以上可以使用
break;
case Configuration.ORIENTATION_LANDSCAPE://横屏
Log.i(TAG,"横屏");
myCamera.setDisplayOrientation(90); // 在2.2以上可以使用
//setContentView(R.layout.activity_main);
default:
break;
}
}
//Activity创建或者从后台重新回到前台时被调用
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"执行了onStart方法");
}
//Activity从后台重新回到前台时被调用
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG,"执行了onRestart方法");
}
//Activity创建或者从被覆盖、后台重新回到前台时被调用
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"执行了onResume方法");
}
//Activity被覆盖到下面或者锁屏时被调用
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"执行了onPause方法");
}
//退出当前Activity或者跳转到新Activity时被调用
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"执行了onStop方法");
}
//退出当前Activity时被调用,调用之后Activity就结束了
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"执行了onDestroy方法");
}
}

Reference:
   
http://simonxanderandroid.blogspot.tw/2011/02/android-camera.html
http://stackoverflow.com/questions/8242749/how-to-set-androidscreenorientation-portrait-for-camera
http://www.kancloud.cn/digest/singwhiledrinking/122022
http://www.cnblogs.com/skyseraph/archive/2012/03/26/2418665.html

No comments:

Post a Comment