1

サービスの開始後、バックグラウンドで画像をキャプチャできるAndroidアプリケーションを作成しようとしています。私はそれをキャプチャしてsdcardに保存することができますが、キャプチャされた画像は少し暗く、私は問題をトレースすることができません。 可能性はありますか?Android Camera in Background

撮影した画像:http://imgur.com/8onjW60

public class MyService extends Service { 

Camera mCamera; 
public String imageEncodeString,imageName; 
public Bitmap bitmap; 
public File file; 

Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { 

    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     if (data != null) { 
      bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 

      if (bitmap != null) { 
       imageName = String.valueOf(System.currentTimeMillis() + ".jpg"); 
       File basedir = new File(Environment.getExternalStorageDirectory() + "/dirr"); 
       file = new File(Environment.getExternalStorageDirectory() + "/dirr" + File.separator + imageName); 
       if (!basedir.isDirectory()) { 
        basedir.mkdirs(); 
       } 
       try { 
        file.createNewFile(); 
        FileOutputStream otstream = new FileOutputStream(file); 
        bitmap.compress(Bitmap.CompressFormat.JPEG,100,otstream); 
        byte[] img =new byte[0]; 
        otstream.write(img); 
        otstream.flush(); 
        otstream.close(); 
       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

      } 
      mCamera.startPreview(); 
     } 

    } 

}; 

public MyService() { 

} 

public IBinder onBind(Intent intent) { 
    // TODO: Return the communication channel to the service. 
    throw new UnsupportedOperationException("Not yet implemented"); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    Toast.makeText(MyService.this, "Starting Service...", Toast.LENGTH_SHORT).show(); 
    Log.d("TAG", "======= service in onStartCommand"); 

    if (checkCameraHardware(this)) { 
     mCamera = getCameraInstance(); 
     if (mCamera != null) { 
      SurfaceView sv = new SurfaceView(this); 

      WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); 
      WindowManager.LayoutParams params = new WindowManager.LayoutParams(1, 1, 
        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
        PixelFormat.TRANSPARENT); 
        params.alpha = 0; 

      SurfaceHolder sh = sv.getHolder(); 
      sv.setZOrderOnTop(true); 
      sh.setFormat(PixelFormat.TRANSPARENT); 

      sh.addCallback(new SurfaceHolder.Callback() { 
       @Override 
       public void surfaceCreated(SurfaceHolder holder) { 
        Camera.Parameters parameters = mCamera.getParameters(); 
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
        parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO); 
        parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO); 
        mCamera.setParameters(parameters); 

        Camera.Parameters p = mCamera.getParameters(); 

        List<Camera.Size> listSize; 

        listSize = p.getSupportedPreviewSizes(); 
        Camera.Size mPreviewSize = listSize.get(2); 
        Log.v("TAG", "preview width = " + mPreviewSize.width 
          + " preview height = " + mPreviewSize.height); 
        p.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 

        listSize = p.getSupportedPictureSizes(); 
        Camera.Size mPictureSize = listSize.get(2); 
        Log.v("TAG", "capture width = " + mPictureSize.width 
          + " capture height = " + mPictureSize.height); 
        p.setPictureSize(mPictureSize.width, mPictureSize.height); 
        mCamera.setParameters(p); 

        try { 
         mCamera.setPreviewDisplay(holder); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        // mCamera.startPreview(); 
        // mCamera.takePicture(null, null, mPictureCallback); // used to takePicture. 

        // Log.d("TAG", "========= Capturing Started"); 

        // mCamera.stopPreview(); 
        // mCamera.release(); 
        // Log.d("TAG", "========== Capturing finished."); 

       } 

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

       } 

       @Override 
       public void surfaceDestroyed(SurfaceHolder holder) { 
        mCamera.stopPreview(); 
        mCamera.release(); 
       } 

      }); 
      wm.addView(sv, params); 
     } else { 
      Log.d("TAG", "==== get Camera from service failed"); 
     } 
}else { 
     Log.d("TAG", "==== There is no camera hardware on device."); 
    } 

    new Handler().postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      Log.d("TAG", "========= Capturing Started"); 
      mCamera.startPreview(); 
      mCamera.takePicture(null, null, mPictureCallback); 
      Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); 
      vibrator.vibrate(1000); 

      Log.d("TAG", "========== Capturing finished."); 
     } 
    }, 5000); 

    return super.onStartCommand(intent, flags, startId); 
} 

@Override 
public void onCreate() { 

    super.onCreate(); 
} 

@Override 
public void onDestroy() { 
    Toast.makeText(MyService.this, "Service Stopped...", Toast.LENGTH_SHORT).show(); 
} 

public static boolean checkCameraHardware(Context context) { 
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { 
     return true; 
    } else { 
     return false; 
    } 
} 

public static Camera getCameraInstance() { 
    Camera c = null; 
    try { 
     c = Camera.open(); 
    } catch (Exception e) { 
     Log.d("TAG", "Open camera failed: " + e); 
    } 

    return c; 
} 

} 

答えて

1

私はtakePictureは()カメラは、プレビュー開始後に照明条件に合わせて調整できるようにビットを遅らせるべきと考えています。

待機する必要がある時間は何百分の1秒で、デバイスと照明条件によって異なります。残念ながらフォーカスとは異なり、露出/ゲイン調整が行われたことを示すコールバックはありません。

成功したonAutoFocus()は、カメラが安定していることを示している可能性があります。もう一つのオプションは、onPreviewFrame()コールバックに登録し、到着するフレームの明るさが安定することを確認することです。

サービスから始めて状況を変えてはいけません。