サーフェイス変更イベントについて
/* * (non-Javadoc) サーフェイス変更イベントの処理 * * @see android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int) */ @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { CameraInformation info = new CameraInformation(); Size previewSize = null; Size pictureSize = null; Log.d(LOG_TAG, "DefaultDisplay Rotation=" + getDefaultDisplayRotation()); Log.d(LOG_TAG, "format=" + format + " width=" + width + " height=" + height); try { if (null != camera) { // プレビューの停止 camera.stopPreview(); // ローテーションを設定 info.setRotation(getDefaultDisplayRotation()); // カメラの設定値を取得 Camera.Parameters params = camera.getParameters(); // プレビューサイズを選択 previewSize = info.getPreviewSize(camera, width, height); // プレビューのサイズを設定 params.setPreviewSize(previewSize.width, previewSize.height); // 画像サイズを取得 pictureSize = info.getPictureSize(camera, this.pictureSize); // 画像のサイズを設定 params.setPictureSize(pictureSize.width, pictureSize.height); // カメラへ設定値を適用 camera.setParameters(params); // プレビューの開始 camera.startPreview(); Log.d(LOG_TAG, "preview width=" + previewSize.width + " height=" + previewSize.height); Log.d(LOG_TAG, "picture width=" + pictureSize.width + " height=" + pictureSize.height); } } catch (Exception e) { Log.e(LOG_TAG, "Can not preview. " + e.getMessage()); } }
カメラのプレビュー表示につて、説明をします。
1、プレビューの停止
使用しているカメラを camera.stopPreview() で停止する。
プレビューの停止しなくてもいいけど、したほうが安全である。
なぜか?
例えば、工場の機械を設定してくれよとお客様から要望があったとする。
「機械は止めちゃだめだよ。止めたら損害賠償を請求するからね!」なんて無茶な要件と同じである。
コンベアに巻き込まれて、手や足が挟まれてぐちゃぐちゃになってもいい、動いている機械の内部に入って設定するぞ!
なんて、猛者ならいいですよ。
自分にはできない・・・けど、金銭保障するからお願いと、懇願されたらするかも・・・
2、 ローテーションを設定
スマホやタブレットを立てて使用しているか横向きで使用しているかを設定します。
ほとんどのサイトで、横で使用するのが標準だけど立てて使用する。(呪縛)
標準が横なら横でいいじゃん!
使う人が、横で使おうがねっころがって逆さまで使おうがいいのでは?
回転させたくなかったら、使う人が回転をロック(固定)すればいいだけでしょう?
なので、「横でも縦でも好きにしてくれ!」要件を実装します。
さてと、回転の情報をどこから取得するかというと、ウインドウマネージャに聞くといいらしいので、getDefaultDisplayRotation() を実装します。
/** * 回転の状態を取得 * * @return Surface.ROTATION_0 or Surface.ROTATION_90 , or Surface.ROTATION_180, or Surface.ROTATION_270. */ public int getDefaultDisplayRotation() { return getWindowManager().getDefaultDisplay().getRotation(); } /** * ウインドウマネージャーを取得 * * @return */ protected WindowManager getWindowManager() { return (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE); }
ウインドウマネージャーを呼び出して、デフォルトのディスプレイ情報から回転情報を取得します。
そんじゃ、ウインドウマネジャーはどこから呼び出せばいいかというと、コンテキストからサービスを指定して取得します。
ウインドウマネジャーは、よそものから使われたくないので protected にしておきます。
参考書やよくあるサイトだと
public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); }
「このソースを参考にして回転情報の取得メソッドを実装します。」とか書かれてるけど、なんでやねん!
難しいこと書かんで、いいでしょう!
「コンテキストからサービスを指定して、ウインドウマネージャーを呼び出し、デフォルトのディスプレイ情報から回転情報を取得します。」
これでいいのだ!
長くなりそうなので、次へと続く・・・ To Be Continued…