2015-10-27 2 views
2

Я использую класс ниже, чтобы сделать снимок на Android, и я хочу сделать снимок с помощью передней камеры. Я добавил необходимые разрешения для файла манифеста:Невозможно сделать снимок в android

public class CameraController extends AsyncTask{ 

    final Context context; 

    private boolean hasCamera; 

    private Camera camera; 
    private int cameraId; 

    public CameraController(Context c){ 
     context = c.getApplicationContext(); 

     if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){ 
      cameraId = getFrontCameraId(); 

      if(cameraId != -1){ 
       hasCamera = true; 
      }else{ 
       hasCamera = false; 
      } 
     }else{ 
      hasCamera = false; 
     } 
    } 


    public void getCameraInstance(){ 
     camera = null; 

     if(hasCamera){ 
      try{ 
       camera = Camera.open(cameraId); 
       prepareCamera(); 
      } 
      catch(Exception e){ 
       hasCamera = false; 
      } 
     } 
    } 

    public void takePicture(){ 
     if(hasCamera){ 
      camera.takePicture(null,null,mPicture); 
     } 
    } 

    public void releaseCamera(){ 
     if(camera != null){ 
      camera.stopPreview(); 
      camera.release(); 
      camera = null; 
     } 
    } 

    private int getFrontCameraId(){ 
     int camId = -1; 
     int numberOfCameras = Camera.getNumberOfCameras(); 
     CameraInfo ci = new CameraInfo(); 

     for(int i = 0;i < numberOfCameras;i++){ 
      Camera.getCameraInfo(i,ci); 
      if(ci.facing == CameraInfo.CAMERA_FACING_FRONT){ 
       camId = i; 
      } 
     } 

     return camId; 
    } 

    private void prepareCamera(){ 
     SurfaceView view = new SurfaceView(context); 

     try{ 
      camera.setPreviewDisplay(view.getHolder()); 
     }catch(IOException e){ 
      throw new RuntimeException(e); 
     } 

     camera.startPreview(); 

     Camera.Parameters params = camera.getParameters(); 
     params.setJpegQuality(100); 

     camera.setParameters(params); 
    } 

    private Camera.PictureCallback mPicture = new Camera.PictureCallback(){ 
     @Override 
     public void onPictureTaken(byte[] data, Camera camera){ 
      File pictureFile = getOutputMediaFile(); 

      if(pictureFile == null){ 
       Log.d("TEST", "Error creating media file, check storage permissions"); 
       return; 
      } 

      try{ 
       Log.d("TEST","File created"); 
       FileOutputStream fos = new FileOutputStream(pictureFile); 
       fos.write(data); 
       fos.close(); 
      }catch(FileNotFoundException e){ 
       Log.d("TEST","File not found: "+e.getMessage()); 
      } catch (IOException e){ 
       Log.d("TEST","Error accessing file: "+e.getMessage()); 
      } 
     } 
    }; 

    private File getOutputMediaFile(){ 

     File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp"); 

     if(!mediaStorageDir.exists()){ 
      if(!mediaStorageDir.mkdirs()){ 
       return null; 
      } 
     } 

     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 

     File mediaFile; 
     mediaFile = new File(mediaStorageDir.getPath()+File.separator+"IMG_"+timeStamp+".jpg"); 

     return mediaFile; 
    } 

    @Override 
    protected Object doInBackground(Object[] params) { 
     try{ 

      takePicture(); 
      return "1"; 
     }catch(Exception e){ 
      return "-1"; 
     } 
    } 
    @Override 
    protected void onPostExecute(Object o) { 
     super.onPostExecute(o); 
     releaseCamera(); 

    } 
} 

и назвать его в моем mainActivity же это:

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     context = this; 
     CameraController cc = new CameraController(context); 
     cc.getCameraInstance(); 
     cc.execute(); 
} 

Приведенный выше код не работает, и не принимать какие-либо картины. Я отлаживал код и замечал, что onPictureTaken не вызывается.

+0

Возможно, это поможет вам http://stackoverflow.com/questions/6200369/picturecallback-onpicturetaken-never-called – Lazai

+0

С первого взгляда вы вызываете 'camera.takePicture()' слишком рано , Ограничение состоит в том, что вам разрешено делать это только после начала предварительного просмотра (это означает, что для некоторых устройств мы должны ждать до 300 мс после вызова функции startPreview() '). –

ответ

0

попробуйте этот код: это mainactivity

public class AndroidCameraExample extends Activity implements SensorEventListener,FaceDetectionListener{ 
    private Camera mCamera; 
    private CameraPreview mPreview; 
    private PictureCallback mPicture; 
    private Button capture, switchCamera; 
    private Context myContext; 
    private LinearLayout cameraPreview; 
    private boolean cameraFront = false,hasaccel,changed=false; 
    SensorManager sm; 
    List<Sensor> s; 
    Sensor sensor; 
    String photopath; 
    int ax=100,ay; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
     WindowManager.LayoutParams layout = getWindow().getAttributes(); 
     layout.screenBrightness = 1F; 
     getWindow().setAttributes(layout); 
     myContext = this; 
     initialize(); 
     hasaccel = checkaccelerometer(); 

    } 

    private int findFrontFacingCamera() { 
     int cameraId = -1; 
     // Search for the front facing camera 
     int numberOfCameras = Camera.getNumberOfCameras(); 
     for (int i = 0; i < numberOfCameras; i++) { 
      CameraInfo info = new CameraInfo(); 
      Camera.getCameraInfo(i, info); 
      if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { 
       cameraId = i; 
       cameraFront = true; 
       break; 
      } 
     } 
     return cameraId; 
    } 

    private int findBackFacingCamera() { 
     int cameraId = -1; 
     //Search for the back facing camera 
     //get the number of cameras 
     int numberOfCameras = Camera.getNumberOfCameras(); 
     //for every camera check 
     for (int i = 0; i < numberOfCameras; i++) { 
      CameraInfo info = new CameraInfo(); 
      Camera.getCameraInfo(i, info); 
      if (info.facing == CameraInfo.CAMERA_FACING_BACK) { 
       cameraId = i; 
       cameraFront = false; 
       break; 
      } 
     } 
     return cameraId; 
    } 

    public void onResume() { 
     super.onResume(); 
     if (!hasCamera(myContext)) { 
      Toast toast = Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG); 
      toast.show(); 
      finish(); 
     } 
     if (mCamera == null) { 
      //if the front facing camera does not exist 
      if (findFrontFacingCamera() < 0) { 
       Toast.makeText(this, "No front facing camera found.", Toast.LENGTH_LONG).show(); 
       switchCamera.setVisibility(View.GONE); 
      }  
      int cameraId = findFrontFacingCamera(); 
      //Mayur 
      mCamera = Camera.open((cameraId)); 

     // mCamera.setFaceDetectionListener(this); 
     // mCamera.startFaceDetection(); 
      setCameraDisplayOrientation(this, cameraId, mCamera); 
      mPicture = getPictureCallback(); 
      mPreview.refreshCamera(mCamera); 
     } 
    } 

    public void initialize() { 
     cameraPreview = (LinearLayout) findViewById(R.id.camera_preview); 
     mPreview = new CameraPreview(myContext, mCamera); 
     cameraPreview.addView(mPreview); 

     capture = (Button) findViewById(R.id.button_capture); 
     capture.setOnClickListener(captrureListener); 

     switchCamera = (Button) findViewById(R.id.button_ChangeCamera); 
     switchCamera.setOnClickListener(switchCameraListener); 
    } 

    OnClickListener switchCameraListener = new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      //get the number of cameras 
      int camerasNumber = Camera.getNumberOfCameras(); 
      if (camerasNumber > 1) { 
       //release the old camera instance 
       //switch camera, from the front and the back and vice versa 

       releaseCamera(); 
       chooseCamera(); 
      } else { 
       Toast toast = Toast.makeText(myContext, "Sorry, your phone has only one camera!", Toast.LENGTH_LONG); 
       toast.show(); 
      } 
     } 
    }; 

    public void chooseCamera() { 
     //if the camera preview is the front 
     if (cameraFront) { 
      int cameraId = findBackFacingCamera(); 
      if (cameraId >= 0) { 
       //open the backFacingCamera 
       //set a picture callback 
       //refresh the preview 

       mCamera = Camera.open(cameraId);     
       mPicture = getPictureCallback();    
       mPreview.refreshCamera(mCamera); 
      } 
     } else { 
      int cameraId = findFrontFacingCamera(); 
      if (cameraId >= 0) { 
       //open the backFacingCamera 
       //set a picture callback 
       //refresh the preview 

       mCamera = Camera.open(cameraId); 
       mPicture = getPictureCallback(); 
       mPreview.refreshCamera(mCamera); 
      } 
     } 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     //when on Pause, release camera in order to be used from other applications 
     releaseCamera(); 
    } 

    private boolean hasCamera(Context context) { 
     //check if the device has camera 
     if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    private PictureCallback getPictureCallback() { 
     PictureCallback picture = new PictureCallback() { 

      @Override 
      public void onPictureTaken(byte[] data, Camera camera) { 
       //make a new picture file 
       File pictureFile = getOutputMediaFile(); 
       // Location of stored image 
       Log.d("Mayur", "Picture: "+pictureFile); 
       Log.d("Mayur","Data: "+data); 
       if (pictureFile == null) { 
        return; 
       } 
       try { 
        //check orientation and rotate if necessary 

        //write the file 
        while(!changed) 
        { 
        Log.d("Parth", "X: "+ax); 
        } 
        int rotate=-90; 
       /* if((ax<=5 && ax>=-1) && (ay>=6 && ay<=9)) 
        { 
         rotate=-90; 
        } 
        else if((ax<=9 && ax>=6) && (ay>=-1 && ay<=5)) 
        { 
         rotate=-90; 
        } 
        else if((ax<=-6 && ax>=-9) && (ay>=-1 && ay<=5)) 
        { 
         rotate = -180; 
        } 
        else if((ax<=5 && ax>=-1) && (ay>=-9 && ay<=-6)) 
        { 
         rotate = 90; 
        } 
        */ 
        Log.d("Parth", "X: "+ax+" Y:"+ay); 
        Matrix matrix = new Matrix(); 
        if(android.os.Build.VERSION.SDK_INT>13) 
        { 
         float[] mirrorY = { -1, 0, 0, 0, 1, 0, 0, 0, 1}; 
         Matrix matrixMirrorY = new Matrix(); 
         matrixMirrorY.setValues(mirrorY); 

         matrix.postConcat(matrixMirrorY); 

         matrix.preRotate(rotate); 

        } 

        Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length); 
        int i = ExifInterface.ORIENTATION_FLIP_HORIZONTAL; 
        bmp = Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,true); 
        FileOutputStream fos = new FileOutputStream(pictureFile); 
        bmp.compress(Bitmap.CompressFormat.JPEG, 85, fos); 
        photopath = pictureFile.getAbsolutePath(); 
        fos.flush(); 
        fos.close(); 
        bmp.recycle(); 
        //Toast toast = Toast.makeText(myContext, "Picture saved: " + pictureFile.getName(), Toast.LENGTH_LONG); 
        //toast.show(); 
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(pictureFile))); 
        Intent intent = new Intent(myContext, LayoutTest1Activity.class); 
        intent.putExtra("path", photopath); 
        startActivity(intent); 
        finish(); 

       } catch (FileNotFoundException e) { 
       } catch (IOException e) { 
       } 

       //refresh camera to continue preview 
       mPreview.refreshCamera(mCamera); 
      } 
     }; 
     return picture; 
    } 

    protected void checkorientation() { 
     // TODO Auto-generated method stub 
     sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
     sm.registerListener(this, sensor,SensorManager.SENSOR_DELAY_FASTEST); 

    } 

    OnClickListener captrureListener = new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      //Mayur 
      checkorientation(); 
      Camera.Parameters params=mCamera.getParameters(); 
      List<Size> sizes =params.getSupportedPictureSizes(); 
      Size mSize=null; 
      int temp=0; 
//   for(Size size:sizes) 
//   { 
//    mSize=size; 
//    Log.d("Mayur", "H: "+mSize.height+" W: "+mSize.width); 
//   } 

      mSize=sizes.get(0); //taking largest resolution 

      Log.d("Mayur", "Loaded with H: "+mSize.height+"W: "+mSize.width); 
      params.setPictureSize(mSize.width, mSize.height); 
      mCamera.setParameters(params); 

      // 
      mCamera.takePicture(null, null, mPicture); 

     } 


    }; 
    private boolean checkaccelerometer() { 
     sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
     s = new ArrayList<Sensor>(); 
     s = sm.getSensorList(Sensor.TYPE_ACCELEROMETER); 
     if(s.size()>0) 
     { 
      Toast.makeText(myContext, "has accelerometer", Toast.LENGTH_SHORT).show(); 
      return true; 
     } 
     return false; 
     // TODO Auto-generated method stub 
    } 
    //make picture and save to a folder 
    private static File getOutputMediaFile() { 
     //make a new file directory inside the "sdcard" folder 
     File mediaStorageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Creaa"); 
     mediaStorageDir.mkdirs(); 
     //if this "Creaa Camera folder does not exist 
     if (!mediaStorageDir.exists()) { 
      //if you cannot make this folder return 
      if (!mediaStorageDir.mkdirs()) { 
       return null; 
      } 
     } 

     //take the current timeStamp 
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
     File mediaFile; 
     //and make a media file: 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + "mypic_" + timeStamp + ".jpg"); 
     return mediaFile; 
    } 

    private void releaseCamera() { 
     // stop and release camera 
     if (mCamera != null) { 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

    @Override 
    public void onSensorChanged(SensorEvent event) { 
     // TODO Auto-generated method stub 
     ax = (int) event.values[0]; 
     ay = (int) event.values[1]; 
     sm.unregisterListener(this); 
     Toast.makeText(myContext, "X : "+ax+" Y: "+ay, Toast.LENGTH_SHORT).show(); 
     changed=true; 
    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
     // TODO Auto-generated method stub 

    } 

    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; 
     } 
     Log.d("Parth", "Result : "+result); 
     camera.setDisplayOrientation(result); 
    } 

    @Override 
    public void onFaceDetection(Face[] faces, Camera camera) { 
     // TODO Auto-generated method stub 
     Toast.makeText(this, "facedeteted", Toast.LENGTH_SHORT).show(); 
     if(faces.length>0) 
     Log.d("Parth", "mouth:"+faces[0].mouth.x+"\nrect :"+faces[0].rect.bottom); 
    } 


} 

и второй класс: это для камеры предварительного просмотра, как вам нужно SurfaceView для передней камеры unlikle задней камеры, которые мы начинаем с умыслом.

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
    private SurfaceHolder mHolder; 
    private Camera mCamera; 

    public CameraPreview(Context context, Camera camera) { 
     super(context); 
     mCamera = camera; 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 
     // deprecated setting, but required on Android versions prior to 3.0 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     try { 
      // create the surface and start camera preview 
      if (mCamera == null) { 
       mCamera.setPreviewDisplay(holder); 
       mCamera.startPreview(); 
      } 
     } catch (IOException e) { 
      Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage()); 
     } 
    } 

    public void refreshCamera(Camera camera) { 
     if (mHolder.getSurface() == null) { 
      // preview surface does not exist 
      return; 
     } 
     // stop preview before making changes 
     try { 
      mCamera.stopPreview(); 
     } catch (Exception e) { 
      // ignore: tried to stop a non-existent preview 
     } 
     // set preview size and make any resize, rotate or 
     // reformatting changes here 
     // start preview with new settings 
     setCamera(camera); 
     try { 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 
     } catch (Exception e) { 
      Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage()); 
     } 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     // If your preview can change or rotate, take care of those events here. 
     // Make sure to stop the preview before resizing or reformatting it. 
     refreshCamera(mCamera); 
    } 

    public void setCamera(Camera camera) { 
     //method to set a camera instance 
     mCamera = camera; 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 
     // mCamera.release(); 

    } 
} 

Этот код используется для прямого запуска передней камеры. используйте оба класса выше