Android 手机上实现触摸自动聚焦代码笔记

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); } }

你可能感兴趣的:(知识库)