53 votes

Utiliser la lampe torche de l'appareil photo dans Android

J'essaie d'utiliser la lampe de poche LED des caméras dans un widget. J'ai trouvé plusieurs fils de discussion sur ce sujet (par ex. celui mentionné plus tard..) Maintenant, j'essaie de contrôler la lumière en utilisant.. :

Camera cam = Camera.open();     
Parameters p = cam.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
cam.setParameters(p);
cam.release();

Dans le AndroidManifest.xml j'ai essayé différentes permissions, actuellement j'ai :

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />

Je teste cela sur mon Galaxy Tab car je n'ai pas d'autres appareils Android sous la main : la lumière ne s'allume pas. J'ai donc quelques questions maintenant :

  1. Y a-t-il un moyen de tester le comportement de la lumière des DEL dans l'émulateur ?
  2. Est-ce que je fais quelque chose de mal ici ?
  3. Selon ce question qui traite du même problème, il fonctionne différemment sur le Galaxy Tab. Comment ?
  4. Enfin, si le fonctionnement est différent, je commence à me demander s'il s'agit uniquement de la Galaxy Tab ou si d'autres appareils utilisent également des méthodes différentes. Ce serait alors difficile à tester et cela me semble plutôt étrange.

Merci pour tout renseignement !

Au fait, j'ai rapidement testé avec Réglages rapides qui est mentionné à plusieurs reprises ici. La lampe de poche ne fonctionne pas non plus avec les réglages rapides.

Notez que la Galaxy Tab stil utilise Android 2.2. Je vois qu'il y a eu quelques changements entre la 2.2 et la 2.3.

Commentaire : Je sais que cela doit fonctionner d'une manière ou d'une autre car j'ai trouvé d'autres applications sur le marché qui fonctionnent parfaitement avec le Galaxy Tab.

Commentaire 2 : Si je configure cam.setParameters(p) ; et demande directement à la caméra l'état actuel avec getFlashMode(), elle renvoie correctement FLASH_MODE_TORCH. Cependant, si je relâche la caméra et la rouvre, elle renvoie FLASH_MODE_OFF. C'est presque comme si l'objet Caméra reconnaissait la demande mais ne la transmettait pas vraiment au matériel !

--

Après le commentaire de Konstantins, j'ai supprimé la partie cam.release() ;. Il a raison, les paramètres ne sont pas persistants si vous relâchez la caméra. Si vous utilisez à nouveau cam.open(), vous obtiendrez une nouvelle instance avec la lumière éteinte. La lumière ne fonctionne toujours pas sur la galaxy tab. Donc, je suppose qu'il est difficile de garder la lumière allumée si vous essayez de la contrôler via un widget. Dès que le service de fond est terminé, l'objet caméra est libéré automatiquement et donc la lumière s'éteint à nouveau. Mes questions demeurent, notamment pourquoi la caméra ne s'allume pas en premier lieu.

34voto

Kevin TeslaCoil Points 4273

Chaque appareil est un peu différent. Samsung aime particulièrement rendre les choses compliquées pour les développeurs d'applications.

Sur le Galaxy Tab, vous devriez pouvoir le faire :

Camera cam;
void ledon() {
    cam = Camera.open();     
    Parameters params = cam.getParameters();
    params.setFlashMode(Parameters.FLASH_MODE_ON);
    cam.setParameters(params);
    cam.startPreview();
    cam.autoFocus(new AutoFocusCallback() {
                public void onAutoFocus(boolean success, Camera camera) {
                }
            });
}

void ledoff() {
    cam.stopPreview();
    cam.release();
}

Si cela ne fonctionne pas, il peut s'agir de régler FLASH_MODE_OFF initialement et de le modifier après le startPreview.

18voto

Vous ne devez pas relâcher la caméra après avoir réglé les paramètres. J'ai constaté que le flash est activé (en mode torche) après avoir lancé l'aperçu. ( S'applique au motorola defy, 2.1 )

Il est également judicieux de vérifier les modes de flash pris en charge avant d'essayer de les activer.

Jouer avec les paramètres de l'appareil photo sur Android est un vaudou des plus sombres : De nombreux appareils se comportent différemment et il ne semble pas y avoir de moyen fiable de les cibler tous avec un seul morceau de code. Le pari le plus sûr est de toujours configurer correctement votre appareil photo lorsque vous utilisez votre ordinateur. onResume() est appelée. J'envisagerais également de faire la même chose dans onConfigChange() car au moins le verrouillage d'écran de Motorola peut forcer votre application à passer en mode portrait, en la redémarrant complètement.

P.s. Je suppose que lorsque vous fermez l'appareil photo, l'application native de l'appareil photo est fermée, puis recréée dans un nouvel état.

11voto

Siddhpura Amit Points 3562

J'ai procédé de la manière suivante, qui fonctionne sur de nombreux téléphones :

 String manuName = android.os.Build.MANUFACTURER.toLowerCase();
 Camera mCamera;

Le code ci-dessous montre comment éteindre et allumer les lumières :

  private void processOnClick() {

    if (manuName.contains("motorola")) {
        DroidLED led;
        try {
            led = new DroidLED();
            led.enable(true);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } else {
        if (mCamera == null) {
            try {
                mCamera = Camera.open();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (mCamera != null) {

            final Parameters params = mCamera.getParameters();

            List<String> flashModes = params.getSupportedFlashModes();

            if (flashModes == null) {
                return;
            } else {
                if (count == 0) {
                    params.setFlashMode(Parameters.FLASH_MODE_OFF);
                    mCamera.setParameters(params);
                    mCamera.startPreview();
                }

                String flashMode = params.getFlashMode();

                if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) {

                    if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) {
                        params.setFlashMode(Parameters.FLASH_MODE_TORCH);
                        mCamera.setParameters(params);
                    } else {
                        // Toast.makeText(this,
                        // "Flash mode (torch) not supported",Toast.LENGTH_LONG).show();

                        params.setFlashMode(Parameters.FLASH_MODE_ON);

                        mCamera.setParameters(params);
                        try {
                            mCamera.autoFocus(new AutoFocusCallback() {
                                public void onAutoFocus(boolean success, Camera camera) {
                                    count = 1;
                                }
                            });
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    if (mCamera == null) {
        return;
    }
}

private void processOffClick() {

    if (manuName.contains("motorola")) {
        DroidLED led;
        try {
            led = new DroidLED();
            led.enable(false);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } else {
        if (mCamera != null) {
            count = 0;
            mCamera.stopPreview();
        }
    }
}

Ci-dessous, la classe DroidLED :

 class DroidLED {

    private Object svc = null;
    private Method getFlashlightEnabled = null;
    private Method setFlashlightEnabled = null;

    @SuppressWarnings("unchecked")
    public DroidLED() throws Exception {
            try {
                    // call ServiceManager.getService("hardware") to get an IBinder for the service.
                    // this appears to be totally undocumented and not exposed in the SDK whatsoever.
                    Class sm = Class.forName("android.os.ServiceManager");
                    Object hwBinder = sm.getMethod("getService", String.class).invoke(null, "hardware");

                    // get the hardware service stub. this seems to just get us one step closer to the proxy
                    Class hwsstub = Class.forName("android.os.IHardwareService$Stub");
                    Method asInterface = hwsstub.getMethod("asInterface", android.os.IBinder.class);
                    svc = asInterface.invoke(null, (IBinder) hwBinder);

                    // grab the class (android.os.IHardwareService$Stub$Proxy) so we can reflect on its methods
                    Class proxy = svc.getClass();

                    // save methods
                    getFlashlightEnabled = proxy.getMethod("getFlashlightEnabled");
                    setFlashlightEnabled = proxy.getMethod("setFlashlightEnabled", boolean.class);
            }
            catch(Exception e) {
                    throw new Exception("LED could not be initialized");
            }
    }

    public boolean isEnabled() {
            try {
                    return getFlashlightEnabled.invoke(svc).equals(true);
            }
            catch(Exception e) {
                    return false;
            }
    }

    public void enable(boolean tf) {
            try {
                    setFlashlightEnabled.invoke(svc, tf);
            }
            catch(Exception e) {}
    }

}

Les permissions suivantes doivent être définies dans votre AndroidManifest.xml :

 <uses-permission android:name="android.permission.CAMERA" />
 <uses-permission android:name="android.permission.FLASHLIGHT"/>
 <uses-feature android:name="android.hardware.camera" />
 <uses-feature android:name="android.hardware.camera.autofocus" />
 <uses-feature android:name="android.hardware.camera.flash" />

8voto

Horaceman Points 525

Cela fonctionne pour moi sur un HTC Desire... (avec 2.2) (Bien sûr avec les permissions pour la caméra et la lampe de poche) :

    Camera mycam = Camera.open();
    Parameters p = mycam.getParameters();// = mycam.getParameters();
    p.setFlashMode(Parameters.FLASH_MODE_TORCH); 
    mycam.setParameters(p); //time passes 
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    p.setFlashMode(Parameters.FLASH_MODE_OFF);
    mycam.release();

4voto

Timo Points 956

Vous pouvez également essayer d'ajouter une vue de surface. Jetez un coup d'œil à ma réponse à La lampe de poche LED du Galaxy Nexus est contrôlable par quelle API ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X