Подтвердить что ты не робот

Использовать фонарик камеры в Android

Я пытаюсь использовать светодиодный фонарик камеры в виджетах. Я нашел несколько тем по этой теме (т.е. тот, о котором уже упоминалось выше..), теперь я пытаюсь контролировать свет, используя:

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

В 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" />

Я тестирую это на своей Galaxy Tab, так как у меня нет других устройств Android под рукой: свет не включается. Поэтому у меня есть несколько вопросов:

  • Есть ли способ проверить поведение светодиодного света в эмуляторе?
  • Я делаю что-то не так здесь?
  • В соответствии с этим вопросом, который касается одной и той же проблемы, он работает по-разному на вкладке Galaxy. Как?
  • И, наконец, если он работает по-другому, я начинаю сомневаться, что это просто Galaxy Tab или если другие устройства используют разные методы. Тогда было бы трудно проверить, и мне кажется довольно странным.

Спасибо за понимание!

Кстати, я быстро проверил quick-settings, который упоминается здесь несколько раз. Фонарик также не работает с быстрыми настройками.

Обратите внимание, что Galaxy Tab stil использует Android 2.2. Я вижу, что произошли некоторые изменения между 2.2 и 2.3.

Комментарий: Я знаю, что это должно работать как-то, поскольку я нашел другие приложения на рынке, которые отлично работают с Galaxy Tab.

Комментарий 2: Если я установил cam.setParameters(p); и прямо спросите камеру о текущем состоянии с помощью getFlashMode(), он корректно возвращает FLASH_MODE_TORCH. Однако, если я отпущу камеру и снова открою ее, она вернет FLASH_MODE_OFF. Это почти так, как если бы объект Camera признавал запрос, но на самом деле не передает его аппаратным средствам??

-

После комментария Konstantins я удалил cam.release(); часть. Он прав, настройки не сохраняются, если вы отпустите камеру. Если вы снова используете cam.open(), вы получите новый экземпляр с выключенным светом. Тем не менее, свет все еще не работает на вкладке галактики. Так что, я думаю, это трудно держать свет, если вы пытаетесь контролировать его через виджет. Как только фоновая служба будет завершена, объект камеры автоматически отпустится, и, следовательно, свет снова выключится. Мои вопросы все еще остаются, особенно, почему камера не включается в первую очередь.

4b9b3361

Ответ 1

Каждое устройство немного отличается. Samsung особенно любит усложнять работу разработчиков приложений.

На вкладке Galaxy вам должно быть хорошо:

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();
}

Если это не сработает, возможно, сначала нужно установить FLASH_MODE_OFF и изменить его после startPreview.

Ответ 2

Вы не должны отпускать камеру после установки параметров. Я обнаружил, что вспышка активирована (в режиме факела) после того, как я начал предварительный просмотр. (Относится к motorola defy, 2.1)

Также рекомендуется проверить поддерживаемые режимы вспышки, прежде чем пытаться их активировать.

Беспокойство с настройками камеры на андроиде является самым темным вуду: многие устройства ведут себя по-разному и, похоже, нет надежного способа нацеливания их всех на один кусок кода. Самая безопасная ставка - всегда правильно настроить камеру, когда вызывается метод onResume(). Я также хотел бы сделать то же самое в onConfigChange(), потому что хотя бы блокиратор экрана Motorola может заставить ваше приложение в портретном режиме, полностью перезапустив его.

P.s. Я полагаю, что когда вы закрываете камеру, приложение для родной камеры закрывается, а затем воссоздается в новом состоянии.

Ответ 3

Я сделал это следующим образом, который работает на многих телефонах:

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

В приведенном ниже коде показано, как выключать и включать свет:

  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();
        }
    }
}

Ниже приведен класс 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) {}
    }

}

В вашем 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" />

Ответ 4

Это работает для меня на HTC Desire... (с 2.2) (Конечно, с разрешениями камеры и фонарика):

    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();

Ответ 7

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);
}

установить разрешение в Манифест:

<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" />