web-dev-qa-db-fra.com

Utilisez la lampe de poche de l'appareil photo dans Android

J'essaie d'utiliser la lampe de poche LED de l'appareil photo dans un widget. J'ai trouvé plusieurs fils sur ce sujet (c'est-à-dire 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 AndroidManifest.xml, j'ai essayé différentes autorisations, j'ai actuellement:

<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 ma Galaxy Tab car je n'ai pas d'autre appareil Android à portée de main: la lumière ne s'allume pas. J'ai donc quelques questions maintenant:

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

Merci pour tout aperçu!

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

Notez que le Galaxy Tab utilise toujours Android 2.2. Je vois qu'il y a eu quelques changements entre 2.2 et 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 la Galaxy Tab.

Commentaire 2: Si je règle cam.setParameters (p); et demandez 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 Camera connaissait la demande mais ne la transmettait pas vraiment au matériel!?

-

Après le commentaire de Konstantins, j'ai supprimé le cam.release (); partie. Il a raison, les réglages ne sont pas conservés si vous relâchez l'appareil photo. Si vous utilisez à nouveau cam.open (), vous obtiendrez une nouvelle instance avec la lumière éteinte. La lumière ne fonctionne toujours pas sur l'onglet galaxie. 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 d'arrière-plan est terminé, l'objet caméra est automatiquement libéré et la lumière s'éteint donc à nouveau. Mes questions demeurent, en particulier pourquoi la caméra ne s'allume pas en premier lieu.

53
pgruetter

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

Sur la Galaxy Tab, vous devriez être bon avec:

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 définir FLASH_MODE_OFF au départ et de le modifier après startPreview.

34
Kevin TeslaCoil

Vous ne devez pas libérer l'appareil photo après avoir réglé les paramètres. J'ai constaté que le flash est activé (en mode torche) après avoir commencé l'aperçu. (S'applique à Motorola Defy, 2.1)

C'est également une bonne idée de vérifier les modes flash pris en charge, avant d'essayer de les activer.

Jouer avec les paramètres de la caméra sur Android est le vaudou le plus sombre: 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 votre correctement lorsque votre méthode onResume () est appelée. J'envisagerais également de faire de même dans onConfigChange (), car au moins le casier d'écran de Motorola peut forcer votre application en mode portrait , en le redémarrant complètement.

P.s. Je suppose que lorsque vous fermez la caméra, l'application de caméra native est fermée, puis recréée à l'état neuf.

18

Je l'ai fait 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();
        }
    }
}

Voici 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 autorisations 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" />
11
Siddhpura Amit

Cela fonctionne pour moi sur un HTC Desire ... (avec 2.2) (Bien sûr, avec les autorisations Appareil photo et 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();
8
Horaceman

Vous pouvez également essayer d'ajouter une vue de surface. Veuillez jeter un oeil à ma réponse à lampe de poche LED sur Galaxy Nexus contrôlable par quelle API?

4
timoschloesser

Veuillez utiliser ce lien:

http://www.androidhive.info/2013/04/Android-developing-flashlight-application/

C'est très utile pour moi.

3
Yogendra
private Camera camera;
void openCam(){
    camera = Camera.open();
    if (camera != null) {
        Camera.Parameters params = camera.getParameters();
        camera.setParameters(params);
    }
    Camera.Parameters p = camera.getParameters();
    p.setFlashMode(Parameters.FLASH_MODE_TORCH);
    camera.setParameters(p);
}

définir l'autorisation dans Manifest:

<uses-permission
    Android:name="Android.permission.FLASHLIGHT"
    Android:permissionGroup="Android.permission-group.HARDWARE_CONTROLS"
    Android:protectionLevel="normal" />

<uses-feature Android:name="Android.hardware.camera" />
<uses-feature Android:name="Android.hardware.camera.flash" />
1
iKushal