2016-04-16 13 views
1

Ich entwickle eine Android-App, mit der Benutzer einen QR-Code-Inhalt überprüfen und etwas entsprechend lesen Ergebnis ausführen können.Create on click Fokus auf CameraSource - Android QR Code Erkennung

Um die Leistung zu verbessern und ich möchte 2 Methoden implementieren:

  • onClickFocus (der Benutzer die Kamera zu konzentrieren, wenn der Bildschirm geklickt wird)
  • TurnOn/OFF Blitz (der Benutzer erlaubt, zum ein-/ausschalten der Blitz)

ich habe einige graben getan und herausgefunden, dass für Kamera und Blitz verwalte ich die Camera als Objekt zu verwalten selbst in der Lage sein müssen.

Und hier beginnt der Albtraum.

Ich benutze den folgenden Code, um Kameraergebnis anzuzeigen und QR-Codes zu verfolgen.

import android.app.FragmentTransaction; 
import android.content.Context; 


import android.os.Bundle; 
import android.os.Vibrator; 
import android.support.v4.widget.DrawerLayout; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.util.SparseArray; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.widget.TextView; 

import com.google.android.gms.vision.Detector; 
import com.google.android.gms.vision.barcode.Barcode; 
import com.google.android.gms.vision.barcode.BarcodeDetector; 
import java.io.IOException; 



public class MainReadActivity extends AppCompatActivity { 


    public SurfaceView cameraView; 
    private TextView barcodeInfo; 
    public BarcodeDetector barcodeDetector; 
    public CameraSource cameraSource; 
    public Vibrator v; 
    public String textInfo; 
    public DrawerLayout mDrawerLayout; 




    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main_read); 
     v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 

     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout_main); 


     getSupportFragmentManager().findFragmentById(R.id.drawer_layout_main); 

     cameraView = (SurfaceView) findViewById(R.id.camera_view); 


     //barcodeInfo = (TextView) findViewById(R.id.code_info); 

     barcodeDetector = new BarcodeDetector.Builder(this) 
       .setBarcodeFormats(Barcode.QR_CODE) 
       .build(); 


     cameraSource = new CameraSource.Builder(this, barcodeDetector).build(); 



     cameraView.getHolder().addCallback(new SurfaceHolder.Callback() { 

      @Override 
      public void surfaceCreated(SurfaceHolder holder) { 


       try { 
        cameraSource.start(cameraView.getHolder()); 
       } catch (IOException ie) { 
        Log.e("CAMERA SOURCE", ie.getMessage()); 
       } 

      } 


      @Override 
      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
      } 

      @Override 
      public void surfaceDestroyed(SurfaceHolder holder) { 
       cameraSource.stop(); 
      } 

     }); 


     barcodeDetector.setProcessor(new Detector.Processor<Barcode>() { 

      @Override 
      public void release() { 

      } 


      @Override 
      public void receiveDetections(Detector.Detections<Barcode> detections) { 
       final SparseArray<Barcode> barcodes = detections.getDetectedItems(); 

       if (barcodes.size() != 0) { 


        new Runnable() { // Use the post method of the TextView 
         public void run() { 


          v.vibrate(500); 
          // textInfo = barcodes.valueAt(0).displayValue; 

          MyFragmentDialog newf = new MyFragmentDialog(); 
          FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
          transaction.replace(R.id.fragment_container, newf); 

          transaction.addToBackStack("tag"); 
          transaction.commit(); 

         } 
        }; 
       } 
      } 

     }); 







    } 

    public void onBackPressed() { 
     // do nothing 
    } 
} 

Also, ich brauche Zugriff auf die Kamera zu bekommen, von CameraSource (bin ich richtig ?!) Wenn es nicht möglich ist, ich diese CameraSource Klasse von GoogleSamples git verwenden tryed die setFocusMode Methode zu verwenden. .. Aber leider war ich nicht erfolgreich.

Ich habe auch versucht, API 21 zu verwenden, da API 22 no longer supports Kamera und CameraPreferences.

Ich bin mir ziemlich sicher, das ist nicht nur mein Problem, aber ich konnte keinen Weg finden, es zu beheben.

Jeder kann helfen?

FIXED:

einfach dieses CameraSource verwenden (github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms /samples/vision/barcodereader/ui/camera/CameraSource.java). Ja, ich weiß, ich habe es vorgeschlagen ... Aber dieses Mal habe ich mein Problem gelöst! Also, wenn Sie diese verwenden werden, stellen Sie sicher, dass Ihre Kompilierung wie folgt aussieht:

compile 'com.google.android.gms:play-services:8.1.0' 

Antwort

1

diese initialisieren und definieren sie in OnCreate

 Camera.Parameters params; 
    Camera camera; 
    CameraSource cameraSource; 
    SurfaceView cameraView; 
    boolean isFlash = false; 

Anruf changeFlashStatus() Methode Blitz ON drehen und erneut aufrufen Blitz auszuschalten

public void changeFlashStatus() { 


        Field[] declaredFields = CameraSource.class.getDeclaredFields(); 

        for (Field field : declaredFields) { 
         if (field.getType() == Camera.class) { 
          field.setAccessible(true); 
          try { 
           camera = (Camera) field.get(cameraSource); 
           if (camera != null) { 
            params = camera.getParameters(); 

            if(!isFlash){ 
             params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
             flashImage.setColorFilter(getResources().getColor(R.color.yellow)); 
             isFlash = true; 
            } else { 
             params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
             flashImage.setColorFilter(getResources().getColor(R.color.greyLight)); 
             isFlash = false; 

            } 
            camera.setParameters(params); 

           } 

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

          break; 
         } 
        } 

       } 
      }); 

     } 

die Kamera zu bekommen zu konzentrieren, müssen Sie einen bestimmten Bereich (Rect) um es an die Kamera zu übergeben, um den Fokus auf diesen Bereich zu richten.Also müssen wir onTouchListener() für surfaceView implementieren, also wenn wir die surfaceView berühren, erstellen wir MotionEvent, die bestimmen, wo genau Sie die surfaceView berühren, dann können wir Rect von MotionEvent extrahieren.

Rufen Sie initCameraFocusListener() in Ihrem OnCreate. Sicheres Aufrufen nach dem Start der Kamera

private void initCameraFocusListener() { 
     cameraView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 

       cameraFocus(event, cameraSource, Camera.Parameters.FOCUS_MODE_AUTO); 

       return false; 
      } 
     }); 

    } 





private boolean cameraFocus(MotionEvent event, @NonNull CameraSource cameraSource, @NonNull String focusMode) { 
     Field[] declaredFields = CameraSource.class.getDeclaredFields(); 


     int pointerId = event.getPointerId(0); 
     int pointerIndex = event.findPointerIndex(pointerId); 
     // Get the pointer's current position 
     float x = event.getX(pointerIndex); 
     float y = event.getY(pointerIndex); 

     float touchMajor = event.getTouchMajor(); 
     float touchMinor = event.getTouchMinor(); 

     Rect touchRect = new Rect((int)(x - touchMajor/2), (int)(y - touchMinor/2), (int)(x + touchMajor/2), (int)(y + touchMinor/2)); 

     Rect focusArea = new Rect(); 

     focusArea.set(touchRect.left * 2000/cameraView.getWidth() - 1000, 
       touchRect.top * 2000/cameraView.getHeight() - 1000, 
       touchRect.right * 2000/cameraView.getWidth() - 1000, 
       touchRect.bottom * 2000/cameraView.getHeight() - 1000); 

     // Submit focus area to camera 

     ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>(); 
     focusAreas.add(new Camera.Area(focusArea, 1000)); 

     for (Field field : declaredFields) { 
      if (field.getType() == Camera.class) { 
       field.setAccessible(true); 
       try { 
        camera = (Camera) field.get(cameraSource); 
        if (camera != null) { 
         params = camera.getParameters(); 
         params.setFocusMode(focusMode); 
         params.setFocusAreas(focusAreas); 
         camera.setParameters(params); 

         // Start the autofocus operation 

         camera.autoFocus(new Camera.AutoFocusCallback() { 
          @Override 
          public void onAutoFocus(boolean b, Camera camera) { 
           // currently set to auto-focus on single touch 
          } 
         }); 
         return true; 
        } 

        return false; 
       } catch (IllegalAccessException e) { 
        e.printStackTrace(); 
       } 

       break; 
      } 
     } 



     return false; 
    }