2013-01-11 13 views
5

L'unico codice che sono riuscito a ottenere lavorando per scattare una foto con la fotocamera viene eseguito da un'attività. Sono abbastanza certo che è possibile scattare una foto da un servizio o da un AsyncTask lanciato dal servizio.Android: È possibile scattare una foto con la fotocamera da un servizio senza interfaccia utente

Mi sembra che l'API della fotocamera abbia bisogno di un SurfaceView che deve essere collegato a un'interfaccia utente. Forse ho torto. Qualcuno ha scritto un codice in cui una foto può essere presa da un servizio?

risposta

-2

Non credo sia possibile in quanto la fotocamera necessita di una schermata di anteprima. Vedi domanda simile here

+0

E 'possibile farlo con * efficacemente * nessuna anteprima, come mostrato nella domanda che hai collegato. – Sam

+0

@Gridtestmail allora come l'app scatta foto senza che l'utente ne sia a conoscenza? . Hanno avviato un servizio per scattare foto e utilizzare la superficie fittizia/superficie. https://play.google.com/store/apps/details?id=com.zenaapps.backgroundcamera. Come possiamo ottenere lo stesso? potresti fornire qualche esempio di codice, se ne hai? –

5

E 'possibile utilizzare WindowManager in Android.

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

dovrei dire di sì è necessario SurfaceView di scattare una foto, ma non deve essere legato a un certo layout di XML. È possibile aggiungerlo alla classe WindowManager che funziona anche nel servizio. Quindi lo WindowManager qui apre una "finestra" per fare qualsiasi effetto flottante in Android.

In particolare,

È possibile aggiungere un SurfaceView nella WindowManager e impostare i parametri come segue.

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 ha questa funzionalità mentre iOS no. Questo è il motivo per cui puoi avere la chathead di Facebook attiva nella schermata principale in Android piuttosto che in iOS.

Show facebook like chat head from a broadcast receiver in android

+4

È importante notare che questo metodo richiede l'autorizzazione android.permission.SYSTEM_ALERT_WINDOW, che gli utenti potrebbero avere problemi con. – yincrash

+0

Questo ha funzionato per me, sebbene nel tuo esempio di codice manchino alcune parti essenziali. – Sam

+0

@Sam cura di aggiungere le parti essenziali mancanti? – Ben

2

Ecco po 'di codice più completa se siete ancora alla ricerca. Funziona in un servizio (testato):

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

Dai miei esperimenti, la falsa soluzione "SurfaceTexture" ha funzionato su Nexus 4 e HTC One m8 ma non è riuscita su Nexus 5 :( – dzeikei

+0

Qual è stato il problema riscontrato durante il tentativo in Nexus 5? – venkat

+0

Questo non funziona sul mio Sony Xperia M con Android 4.3 a causa della fittizia tecnica 'SurfaceTexture'. – Sam

Problemi correlati