2017-02-05 5 views
0

, пожалуйста, помогите. Есть ли способ использовать Camera API (версия между Android SDK 19 и 17), чтобы заставить камеру сфокусироваться, прежде чем делать снимки при длительном нажатии кнопки закрытия?Камера фокусировки Android при длинном нажатии кнопки закрытия

Другими словами, я долго нажимаю кнопку камеры (и этим я имею в виду, что это может быть кнопка камеры или кнопка на экране), фокус должен начинаться, и в первую секунду я отпускаю эту кнопку, чтобы она картина.

Пожалуйста, помогите.

ответ

0

Хорошо, поэтому для этой функции существуют два метода, которые важны onTouchEvent (где я могу обнаружить кнопку release) и setOnLongClickListener (чтобы обнаружить кнопку с длинным нажатием кнопки, которая снимает фотографию). В приведенном ниже коде я сделал пользовательское представление (называемое классом DrawCameraOptions), которое рисует красный круг на экране над SurfaceView и другим пользовательским представлением (с именем DrawingRectForFocalisationAreaView), который рисует прямоугольник на SurfaceView области фокусировки.

fragment_take_picture.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 


    <SurfaceView 
     android:id="@+id/surfaceView" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

    <customs.cameras.DrawingRectForFocalisationAreaView 
     android:id="@+id/drawingFocusRectangle_FragmentTakePicture" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 


    <customs.cameras.DrawCameraOptions 
     android:id="@+id/takePicture_FragmentTakePicture2" 
     android:layout_width="match_parent" 
     android:layout_height="100dp" 
     android:background="@android:color/transparent" 
     android:layout_alignParentBottom="true"/> 

</RelativeLayout> 

UpdateDrawingFocusAreaRect интерфейс

package network.callbacks; 

import android.graphics.Rect; 
import android.hardware.Camera; 

/** 
* Created by EmiG on 02.02.2017. 
*/ 

public interface UpdateDrawingFocusAreaRect { 

    public void repaintRectFocusArea(final Rect touchRect); 

    public void takePictureOnLongPress(); 
} 

DrawCameraOptions класс

package customs.cameras; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 

import network.callbacks.UpdateDrawingFocusAreaRect; 

/** 
* Created by EmiG on 18.01.2017. 
*/ 

public class DrawCameraOptions extends View { 

    private Paint paint; 
    private UpdateDrawingFocusAreaRect callback; 
    private static final String TAG="TakePictureFragment2"; 

    public DrawCameraOptions(Context context) { 
     super(context); 

     this.initComponets(); 
    } 

    public void setCallback(UpdateDrawingFocusAreaRect callback) { 
     this.callback = callback; 
    } 

    public DrawCameraOptions(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     this.initComponets(); 
    } 

    public DrawCameraOptions(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 

     this.initComponets(); 
    } 

    private void initComponets() 
    { 
     this.paint=new Paint(paint.ANTI_ALIAS_FLAG); 
     this.paint.setStyle(Paint.Style.FILL_AND_STROKE); 
     this.paint.setColor(Color.RED); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     //super.onDraw(canvas); 

     final int width=getWidth() - getPaddingLeft() - getPaddingRight();//of the view 
     final int height=getHeight() - getPaddingTop() - getPaddingBottom(); 
     final int cx=width/2 + getPaddingLeft(); 
     final int cy=height/2 + getPaddingTop(); 
     final float diameter= Math.min(width, height) - paint.getStrokeWidth(); 
     final float radious=diameter/2; 
     canvas.drawCircle(cx,cy,radious,this.paint); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_UP: 
       Log.i(TAG,"ACTION_UP"); 
       if(null!=this.callback) 
       { 
        this.callback.takePictureOnLongPress(); 
       } 
       break; 
     } 
     return super.onTouchEvent(event); 
    } 
} 

DrawingRectForFocalisationAreaView класс

package customs.cameras; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.view.View; 

/** 
* Created by EmiG on 25.01.2017. 
*/ 

public class DrawingRectForFocalisationAreaView extends View { 

    private Paint drawingPaint; 

    boolean haveTouch; 
    private Rect touchArea; 
    private static final int RECT_DIMENSIONS=50; 

    public DrawingRectForFocalisationAreaView(Context context) { 
     super(context); 

     this.init(); 
    } 

    public DrawingRectForFocalisationAreaView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     this.init(); 
    } 

    public DrawingRectForFocalisationAreaView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 

     this.init(); 
    } 

    private void init() 
    { 
     this.drawingPaint = new Paint(); 
     this.drawingPaint.setColor(Color.RED); 
     this.drawingPaint.setStyle(Paint.Style.STROKE); 
     this.drawingPaint.setStrokeWidth(2); 
     this.haveTouch = false; 
    } 

    public void setHaveTouch(boolean t, Rect tArea){ 
     this.drawingPaint.setColor(Color.RED); 
     this.haveTouch = t; 
     this.touchArea = tArea; 
    } 

    public void validateFocus() 
    { 
     if(Color.RED == this.drawingPaint.getColor()) 
     { 
      this.drawingPaint.setColor(Color.GREEN); 
      this.haveTouch=true; 
      invalidate(); 
     } 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     if(this.haveTouch && null!=canvas&& null!=this.drawingPaint){ 

      canvas.drawRect(this.touchArea.left-RECT_DIMENSIONS, this.touchArea.top-RECT_DIMENSIONS, this.touchArea.right+RECT_DIMENSIONS, this.touchArea.bottom+RECT_DIMENSIONS, this.drawingPaint); 
      this.haveTouch=false; 
     } 
    } 
} 

TakePictureFragment2 класс

public class TakePictureFragment2 extends Fragment implements SurfaceHolder.Callback, View.OnTouchListener, UpdateDrawingFocusAreaRect { 

    private static final String TAG = TakePictureFragment2.class.getSimpleName(); 

    //region Focus variabiles 
    private boolean bIsPictureTaking, bIsAutoFocusStarted, bIsAutoFocused, USE_AUTOFOCUS, isFocusated, isLongPressed, canTakePicture; 
    private static final int FOCUS_AREA_SIZE = 300; 
    //endregion 

    private boolean camCondition = false; // conditional variable for camera preview checking and set to false 

    //region Camera object 
    private Camera camera; 
    private SurfaceView surfaceView; 
    private SurfaceHolder surfaceHolder; 

    private Camera.PictureCallback jpegCallback; 
    //endregion 

    //region Execute multiple calculation functionality for drawing 
    private ThreadPoolExecutor threadPoolExecutor; 
    public static final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors(); 
    //endregion 

    //region Custom Objects that draw on the screen 
    private DrawCameraOptions takePictureButton;// Draw shuttbutton for capture image 
    //Desenare pe ecran punct de focalizare 
    private DrawingRectForFocalisationAreaView drawingRectangleOnScreen;//Draw blue rectangle on focus area 
    //endregion 

    //region Fragent methods 
    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     Log.i(TAG, "onCreateView()"); 
     View view = inflater.inflate(R.layout.fragment_take_picture, container, false); 
     if (null != view) { 
      return view; 
     } 

     return super.onCreateView(inflater, container, savedInstanceState); 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     Log.i(TAG, "onActivityCreated()"); 


     this.initOnTouchListener(); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     Log.i(TAG, "onResume()"); 

     this.initComponents(); 

     if (null != camera) { 
      try { 
       camera.setPreviewDisplay(surfaceHolder); // setting preview of camera 
       camera.startPreview(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 
    } 
    //endregion 




//region Initial Components 
    private void initOnTouchListener() { 
     if (null != this.getView()) { 
      this.getView().setOnTouchListener(TakePictureFragment2.this); 
     } 
    } 

    private void initComponents() { 
     if (null != getView()) { 

      this.drawingRectangleOnScreen = (DrawingRectForFocalisationAreaView) getView().findViewById(R.id.drawingFocusRectangle_FragmentTakePicture); 

      takePictureButton = (DrawCameraOptions) getView().findViewById(R.id.takePicture_FragmentTakePicture2); 
      takePictureButton.setCallback(TakePictureFragment2.this); 


      takePictureButton.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        Log.i(TAG,"Simple click"); 

        camera.takePicture(null, null, jpegCallback); 
       } 
      }); 

      takePictureButton.setOnLongClickListener(new View.OnLongClickListener() { 
       @Override 
       public boolean onLongClick(View v) { 
        Log.i(TAG,"Long click"); 
        final Context context=getView().getContext(); 
        isLongPressed=true; 
        synchronized (this) { 
         if (camera != null) { 
          camera.cancelAutoFocus(); 
          if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) { 
           if (!bIsPictureTaking && !bIsAutoFocusStarted) { 
            bIsAutoFocusStarted = true; 
            new AsyncTask<Void, Void, Void>() { 
             @Override 
             protected Void doInBackground(Void... params) { 
              try { 
               Camera.Parameters parameters = camera.getParameters(); 
               if (parameters.getMaxNumMeteringAreas() > 0) { 
                Log.i(TAG, "fancy !"); 
                Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
                Point screenDsiplay=new Point(); 
                display.getSize(screenDsiplay); 
                Rect rect = calculateFocusArea(screenDsiplay.x/2, screenDsiplay.y/2); 
                display=null; 
                screenDsiplay=null; 
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 
                List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>(); 
                meteringAreas.add(new Camera.Area(rect, 1000)); 
                parameters.setFocusAreas(meteringAreas); 

                camera.setParameters(parameters); 
                camera.autoFocus(mAutoFocusTakePictureCallback); 
               } else { 
                camera.autoFocus(mAutoFocusTakePictureCallback); 
               } 
               bIsAutoFocusStarted = false; 
              } catch (Exception e) { 
               Log.e(TAG, "Error " + e.getMessage()); 
               e.printStackTrace(); 
              } 
              System.gc(); 
              return null; 
             } 
            }.execute((Void[]) null); 
           } 
          } else { 
           if (!bIsPictureTaking && !bIsAutoFocusStarted) { 
            bIsAutoFocusStarted = true; 
            new AsyncTask<Void, Void, Void>() { 
             @Override 
             protected Void doInBackground(Void... params) { 
              try { 
               Camera.Parameters parameters = camera.getParameters(); 
               if (parameters.getMaxNumMeteringAreas() > 0) { 
                Log.i(TAG, "fancy !"); 
                Display display2 = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
                Point screenDsiplay2=new Point(); 
                display2.getSize(screenDsiplay2); 
                Rect rect = calculateFocusArea(screenDsiplay2.x/2, screenDsiplay2.y/2); 
                display2=null; 
                screenDsiplay2=null; 

                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 
                List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>(); 
                meteringAreas.add(new Camera.Area(rect, 1000)); 
                parameters.setFocusAreas(meteringAreas); 

                camera.setParameters(parameters); 
                camera.autoFocus(mAutoFocusTakePictureCallback); 
               } else { 
                camera.autoFocus(mAutoFocusTakePictureCallback); 
               } 
               bIsAutoFocusStarted = false; 

              } catch (Exception e) { 
               Log.e(TAG, "Error " + e.getMessage()); 
               e.printStackTrace(); 
              } 

              System.gc(); 
              return null; 
             } 
            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 
           } 
          } 
         } 
        } 

        return true; 
       } 
      }); 


      surfaceView = (SurfaceView) getView().findViewById(R.id.surfaceView); 
      surfaceHolder = surfaceView.getHolder(); 
      // deprecated setting, but required on Android versions prior to 3.0 
      surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

      // Install a SurfaceHolder.Callback so we get notified when the 
      // underlying surface is created and destroyed. 
      surfaceHolder.addCallback(this); 


      jpegCallback = new Camera.PictureCallback() { 
       public void onPictureTaken(final byte[] data, Camera camera) { 
        USE_AUTOFOCUS=false; 
        canTakePicture=false; 
        final Context context = getView().getContext(); 
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) { 
         new AsyncTask<Void, Void, Void>() { 
          @Override 
          protected Void doInBackground(Void... params) { 
           bIsPictureTaking = true; //set it to true to avoid onKeyDown dispatching during taking picture. it may be time-consuming 
           bIsAutoFocused = false; //reset to false 
           bIsAutoFocusStarted = false; //reset to false 

           FileOutputStream outStream = null; 
           try { 
            final GregorianCalendar gregorianCalendar = new GregorianCalendar(); 
            gregorianCalendar.setTime(new Date()); 
            final StringBuffer stringBufferFileName = new StringBuffer(); 
            stringBufferFileName.append(gregorianCalendar.get(Calendar.YEAR)); 
            stringBufferFileName.append("_"); 
            stringBufferFileName.append(gregorianCalendar.get(Calendar.MONTH) + 1); 
            stringBufferFileName.append("_"); 
            stringBufferFileName.append(gregorianCalendar.get(Calendar.DAY_OF_MONTH) + 1); 

            final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "Rompetrol", stringBufferFileName.toString()); 
            if (!root.exists()) { 
             root.mkdirs(); 
            } 
            final File gpxfile = new File(root, System.currentTimeMillis() + ".jpg"); 


            outStream = new FileOutputStream(gpxfile); 
            outStream.write(data); 
            outStream.close(); 
            Log.d("Log", "onPictureTaken - wrote bytes: " + data.length); 

            final AudioManager meng = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 
            int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION); 

            if (volume != 0) { 
             final MediaPlayer _shootMP = MediaPlayer.create(context, Uri.parse("file:///system/media/audio/ui/camera_click.ogg")); 
             _shootMP.start(); 
            } 

            bIsPictureTaking = false; 
            JSONObject jsonObjecte = new JSONObject(); 
            try { 
             jsonObjecte.put(EventBusMessages.OPERATION_TO_PERFORM.getkey(), EventBusMessages.CHANGE_FRAGMENT.getkey()); 
             jsonObjecte.put(EventBusMessages.CHANGE_FRAGMENT.getkey(), FragmentList.DISPLAY_PICTURE_FRAGMENT.getKey()); 
             jsonObjecte.put(EventBusMessages.PICTURE_PATH.getkey(), gpxfile.getAbsolutePath()); 

             EventBus.getDefault().post(jsonObjecte); 
            } catch (JSONException e) { 
             e.printStackTrace(); 
            } 

           } catch (Exception e) { 
            e.printStackTrace(); 
           } 

           return null; 
          } 
         }.execute((Void[]) null); 
        } 
        else 
        { 
         new AsyncTask<Void, Void, Void>() { 
          @Override 
          protected Void doInBackground(Void... params) { 
           bIsPictureTaking = true; //set it to true to avoid onKeyDown dispatching during taking picture. it may be time-consuming 
           bIsAutoFocused = false; //reset to false 
           bIsAutoFocusStarted = false; //reset to false 

           FileOutputStream outStream = null; 
           try { 
            final GregorianCalendar gregorianCalendar = new GregorianCalendar(); 
            gregorianCalendar.setTime(new Date()); 
            final StringBuffer stringBufferFileName = new StringBuffer(); 
            stringBufferFileName.append(gregorianCalendar.get(Calendar.YEAR)); 
            stringBufferFileName.append("_"); 
            stringBufferFileName.append(gregorianCalendar.get(Calendar.MONTH) + 1); 
            stringBufferFileName.append("_"); 
            stringBufferFileName.append(gregorianCalendar.get(Calendar.DAY_OF_MONTH) + 1); 

            final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "Rompetrol", stringBufferFileName.toString()); 
            if (!root.exists()) { 
             root.mkdirs(); 
            } 
            final File gpxfile = new File(root, System.currentTimeMillis() + ".jpg"); 


            outStream = new FileOutputStream(gpxfile); 
            outStream.write(data); 
            outStream.close(); 
            Log.d("Log", "onPictureTaken - wrote bytes: " + data.length); 

            final AudioManager meng = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 
            int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION); 

            if (volume != 0) { 
             final MediaPlayer _shootMP = MediaPlayer.create(context, Uri.parse("file:///system/media/audio/ui/camera_click.ogg")); 
             _shootMP.start(); 
            } 

            bIsPictureTaking = false; 
            JSONObject jsonObjecte = new JSONObject(); 
            try { 
             jsonObjecte.put(EventBusMessages.OPERATION_TO_PERFORM.getkey(), EventBusMessages.CHANGE_FRAGMENT.getkey()); 
             jsonObjecte.put(EventBusMessages.CHANGE_FRAGMENT.getkey(), FragmentList.DISPLAY_PICTURE_FRAGMENT.getKey()); 
             jsonObjecte.put(EventBusMessages.PICTURE_PATH.getkey(), gpxfile.getAbsolutePath()); 

             EventBus.getDefault().post(jsonObjecte); 
            } catch (JSONException e) { 
             e.printStackTrace(); 
            } 

           } catch (Exception e) { 
            e.printStackTrace(); 
           } 

           return null; 
          } 
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,(Void[]) null); 
        } 

        // stop preview before making changes 
        try { 
         camera.stopPreview(); 
         surfaceView.invalidate(); 
         surfaceHolder = null; 
        } catch (Exception e) { 
         // ignore: tried to stop a non-existent preview 
        } 
       } 
      }; 


      this.threadPoolExecutor = new ThreadPoolExecutor(
        NUMBER_OF_CORES * 2, 
        NUMBER_OF_CORES * 2, 
        20L, 
        TimeUnit.SECONDS, 
        new LinkedBlockingQueue<Runnable>()); 

      this.USE_AUTOFOCUS = false; 
      this.bIsPictureTaking = false; //set it to true to avoid onKeyDown dispatching during taking picture. it may be time-consuming 
      this.bIsAutoFocused = false; //reset to false 
      this.bIsAutoFocusStarted = false; //reset to false 
      this.isLongPressed=false;//reset to false 
      this.canTakePicture=false;//reset to false 
     } 
    } 
    //endregion 


public void repaintRectFocusArea(final Rect touchRect) { 
    if (Thread.currentThread() == Looper.getMainLooper().getThread()) { 
     drawingRectangleOnScreen.setHaveTouch(true, touchRect); 
     drawingRectangleOnScreen.invalidate(); 
    } else { 
     getActivity().runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       drawingRectangleOnScreen.setHaveTouch(true, touchRect); 
       drawingRectangleOnScreen.invalidate(); 
      } 
     }); 
    } 
} 


public void takePictureOnLongPress() { 
    if(this.isLongPressed) 
    { 
     Log.i(TAG,"ACTION_BUTTON_RELEASE"); 
     this.isLongPressed=false; 
     this.canTakePicture=true; 
     camera.takePicture(null, null, jpegCallback); 
    } 
} 

Пожалуйста, простите мой плохой написания кода.

+0

Для класса TakePictureFragment2 кажется, что stackoverflow не позволяет мне написать весь код, который есть. –