2013-01-11 9 views
5

Der einzige Code, den ich bekommen konnte, um ein Bild mit der Kamera zu machen, läuft von einer Aktivität. Ich bin ziemlich sicher, dass es möglich ist, ein Foto von einem Dienst oder von einer AsyncTask, die vom Dienst gestartet wird, zu machen.Android: Ist es möglich, ein Foto mit der Kamera von einem Dienst ohne Benutzeroberfläche zu machen

Es scheint mir, dass die Kamera-API ein SurfaceView benötigt, das in eine UI eingebunden werden muss. Vielleicht irre ich mich. Hat jemand Code geschrieben, wo ein Foto von einem Dienst genommen werden kann?

Antwort

-2

Ich glaube nicht, dass dies möglich ist, da die Kamera einen Vorschaubildschirm benötigt. Siehe ähnliche Frage here

+0

Es ist möglich, es mit * effektiv * keine Vorschau zu tun, wie in der Frage gezeigt, die Sie verknüpft haben. – Sam

+0

@Gridtestmail dann, wie die App das Bild ohne Benutzerkenntnis nimmt? . Sie starteten einen Dienst, um ein Bild aufzunehmen und eine Dummy-Oberflächenansicht/Oberflächenstruktur zu verwenden. https://play.google.com/store/apps/details?id=com.zenaapps.backgroundcamera. Wie können wir dasselbe erreichen? Könnten Sie ein Codebeispiel bereitstellen, wenn Sie eines haben? –

5

Es ist möglich mit WindowManager in Android.

https://stackoverflow.com/a/10268650/3047840

ich sagen soll ja Sie müssen SurfaceView ein Bild zu machen, aber es muss nicht zu einem bestimmten XML-Layout gebunden werden. Sie können es der Klasse WindowManager hinzufügen, die sogar im Service funktioniert. So öffnet die WindowManager hier ein "Fenster", damit Sie in Android einen Floating-Effekt ausführen können.

Insbesondere

Sie einen SurfaceView in den WindowManager hinzufügen können und die Parameter einstellen, wie folgend.

mPreview = new CameraPreview(this, mCamera, jpegCallback); 
WindowManager wm = (WindowManager) this 
     .getSystemService(Context.WINDOW_SERVICE); 
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
     WindowManager.LayoutParams.WRAP_CONTENT, 
     WindowManager.LayoutParams.WRAP_CONTENT, 
     WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
     WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
     PixelFormat.TRANSPARENT); 

params.height = 1; 
params.width = 1; 

wm.addView(mPreview, params); 

Android hat diese Funktionalität, während iOS nicht funktioniert. Aus diesem Grund können Sie Facebook-Chathead auf dem Startbildschirm in Android statt in iOS aktivieren.

Show facebook like chat head from a broadcast receiver in android

+4

Es ist wichtig zu beachten, dass diese Methode die android.permission.SYSTEM_ALERT_WINDOW-Berechtigung erfordert, mit der Benutzer möglicherweise Probleme haben. – yincrash

+0

Das funktionierte für mich, obwohl in Ihrem Codebeispiel einige wichtige Teile fehlen. – Sam

+0

@Sam kümmern sich um die fehlenden wesentlichen Teile? – Ben

2

Hier einige weitere komplette Code, wenn Sie noch suchen. Funktioniert in einem Service (getestet):

private void takePhoto() { 

    System.out.println("Preparing to take photo"); 
    Camera camera = null; 

    int cameraCount = 0; 
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 
    cameraCount = Camera.getNumberOfCameras(); 
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) { 
     SystemClock.sleep(1000); 

     Camera.getCameraInfo(camIdx, cameraInfo); 

      try { 
       camera = Camera.open(camIdx); 
      } catch (RuntimeException e) { 
       System.out.println("Camera not available: " + camIdx); 
       camera = null; 
       //e.printStackTrace(); 
      } 
     try{ 
      if (null == camera) { 
       System.out.println("Could not get camera instance"); 
      }else{ 
       System.out.println("Got the camera, creating the dummy surface texture"); 
       //SurfaceTexture dummySurfaceTextureF = new SurfaceTexture(0); 
       try { 
        //camera.setPreviewTexture(dummySurfaceTextureF); 
        camera.setPreviewTexture(new SurfaceTexture(0)); 
        camera.startPreview(); 
       } catch (Exception e) { 
        System.out.println("Could not set the surface preview texture"); 
        e.printStackTrace(); 
       } 
       camera.takePicture(null, null, new Camera.PictureCallback() { 

        @Override 
        public void onPictureTaken(byte[] data, Camera camera) { 
         File pictureFileDir = getDir(); 
         if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) { 
          return; 
         } 
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss"); 
         String date = dateFormat.format(new Date()); 
         String photoFile = "PictureFront_" + "_" + date + ".jpg"; 
         String filename = pictureFileDir.getPath() + File.separator + photoFile; 
         File mainPicture = new File(filename); 
         addImageFile(mainPicture); 

         try { 
          FileOutputStream fos = new FileOutputStream(mainPicture); 
          fos.write(data); 
          fos.close(); 
          System.out.println("image saved"); 
         } catch (Exception error) { 
          System.out.println("Image could not be saved"); 
         } 
         camera.release(); 
        } 
       }); 
      } 
     }catch (Exception e){ 
      camera.release(); 
     } 


    } 
+0

Aus meinen Experimenten arbeitete die Dummy 'SurfaceTexture' Workaround auf Nexus 4 und HTC One M8, aber es scheiterte auf Nexus 5 :( – dzeikei

+0

Was war das Problem, das Sie beim Versuch in Nexus 5 bekommen? – venkat

+0

Dies funktioniert nicht auf meinem Sony Xperia M mit Android 4.3 wegen der Dummy "SurfaceTexture" -Technik. – Sam

Verwandte Themen