Используйте фонарик камеры в Android - PullRequest
53 голосов
/ 31 марта 2011

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

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-устройств под рукой: индикатор не включается.Теперь у меня есть несколько вопросов:

  1. Можно ли проверить поведение светодиодного индикатора в эмуляторе?
  2. Я что-то здесь не так делаю?
  3. Согласно этому вопросу, который касается той же проблемы, он работает по-другому на вкладке Galaxy.Как?
  4. И, наконец, если он работает по-другому, я начинаю задумываться, является ли это просто Galaxy Tab или другие устройства тоже используют другие методы.Это было бы трудно проверить, и мне это кажется довольно странным.

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

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

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

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

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

-

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

Ответы [ 7 ]

34 голосов
/ 07 апреля 2011

Каждое устройство немного отличается. 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.

18 голосов
/ 04 апреля 2011

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

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

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

11 голосов
/ 21 сентября 2012

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

 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" />
8 голосов
/ 05 апреля 2011

Это работает для меня на 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();
4 голосов
/ 02 марта 2012

Вы также можете попытаться добавить вид поверхности.Посмотрите, пожалуйста, мой ответ на светодиодный фонарик на Galaxy Nexus, управляемый каким API?

3 голосов
/ 04 сентября 2014

Пожалуйста, используйте эту ссылку:

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

Это очень полезно для меня.

1 голос
/ 29 марта 2012
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" />
...