2019.3.7 周四测试通过。
不需要单独的写配置xml文件.
package org.vallery.camearfocusdemo;/*
* Copyright 2013 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.app.Activity;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static android.support.v4.math.MathUtils.clamp;
/**
* More or less straight out of TextureView's doc.
*
* TODO: add options for different display sizes, frame rates, camera selection, etc.
*/
public class MainActivity extends Activity implements TextureView.SurfaceTextureListener, View.OnTouchListener, Camera.AutoFocusCallback {
private static final String TAG = MainActivity.TAG;
private Camera mCamera;
private SurfaceTexture mSurfaceTexture;
TextureView textureView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textureView = new TextureView(this);
textureView.setSurfaceTextureListener(this);
textureView.setOnTouchListener(this);
setContentView(textureView);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mSurfaceTexture = surface;
if (!PermissionHelper.hasCameraPermission(this)) {
PermissionHelper.requestCameraPermission(this, false);
} else {
startPreview();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Ignored, Camera does all the work for us
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCamera.stopPreview();
mCamera.release();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// Invoked every time there's a new Camera preview frame
//Log.d(TAG, "updated, ts=" + surface.getTimestamp());
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (!PermissionHelper.hasCameraPermission(this)) {
Toast.makeText(this,
"Camera permission is needed to run this application", Toast.LENGTH_LONG).show();
PermissionHelper.launchPermissionSettings(this);
finish();
} else {
startPreview();
}
}
private void startPreview() {
mCamera = Camera.open();
if (mCamera == null) {
// Seeing this on Nexus 7 2012 -- I guess it wants a rear-facing camera, but
// there isn't one. TODO: fix
throw new RuntimeException("Default camera not available");
}
try {
mCamera.setPreviewTexture(mSurfaceTexture);
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0) {
mCamera.setDisplayOrientation(90);
}
if(display.getRotation() == Surface.ROTATION_270) {
mCamera.setDisplayOrientation(180);
}
mCamera.startPreview();
} catch (IOException ioe) {
// Something bad happened
Log.e(TAG,"Exception starting preview", ioe);
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
onFocus(new Point((int)event.getX(),(int)event.getY()),this);
return true;
}
private Rect calculateTapArea(float x, float y, float coefficient, Camera.Size previewSize) {
float focusAreaSize = 300;
int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
int centerY =0;
int centerX=0;
centerY = (int) (x / textureView.getWidth() * 2000 - 1000);
centerX= (int) (y / textureView.getHeight() * 2000 - 1000);
int left = clamp(centerX - areaSize / 2, -1000, 1000);
int top = clamp(centerY - areaSize / 2, -1000, 1000);
RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
}
private static int clamp(int x, int min, int max) {
if (x > max) {
return max;
}
if (x < min) {
return min;
}
return x;
}
protected void onFocus(Point point, Camera.AutoFocusCallback callback){
Camera.Parameters parameters=mCamera.getParameters();
if (parameters.getMaxNumFocusAreas()<=0) {
mCamera.autoFocus(callback);
return;
}
mCamera.cancelAutoFocus();
List areas=new ArrayList();
List areasMetrix=new ArrayList();
Camera.Size previewSize = parameters.getPreviewSize();
Rect focusRect = calculateTapArea(point.x, point.y, 1.0f, previewSize);
Rect metrixRect = calculateTapArea(point.x, point.y, 1.5f, previewSize);
areas.add(new Camera.Area(focusRect, 1000));
areasMetrix.add(new Camera.Area(metrixRect,1000));
parameters.setMeteringAreas(areasMetrix);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
parameters.setFocusAreas(areas);
try {
mCamera.setParameters(parameters);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
mCamera.autoFocus(callback);
}
@Override
public void onAutoFocus(boolean success, Camera camera) {
Log.e(TAG,"Aauto focus success:"+success);
}
}