1

Ich versuche eine Android-Anwendung zu erstellen, die im Hintergrund Bilder aufnehmen kann, sobald der Dienst gestartet wird. Ich bin in der Lage, es zu erfassen und auf SD-Karte zu speichern, aber das Bild ist etwas dunkel und ich kann das Problem nicht verfolgen. Was könnten die Möglichkeiten sein?Android Kamera im Hintergrund

Aufgenommene Bild: 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; 
} 

} 

Antwort

1

Ich glaube, dass Takepicture() sollte ein wenig verzögert werden, die Kamera an die Lichtbedingungen anpassen zu lassen, nachdem die Vorschau beginnt.

Wie viele hundert Millisekunden Sie warten müssen, hängt vom Gerät und von den Lichtverhältnissen ab. Leider gibt es keinen Rückruf, der anzeigt, dass eine Belichtungs-/Verstärkungsabstimmung durchgeführt wird, im Gegensatz zum Fokus.

Auf den zweiten Gedanken, erfolgreich onAutoFocus() kann ein guter Hinweis darauf sein, dass die Kamera eingestellt ist. Eine andere Möglichkeit ist, sich beim onPreviewFrame() Callback zu registrieren und zu überprüfen, dass die Helligkeit der ankommenden Frames stabil wird.

Start von einem Dienst sollte die Situation nicht ändern.