Используйте фонарик камеры в 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 или другие устройства тоже используют другие методы. Это было бы трудно проверить, и мне это кажется довольно странным.
Спасибо за понимание!
Кстати, я быстро протестировал быстрые настройки, о которых здесь упоминалось несколько раз. Фонарик тоже не работает с быстрыми настройками.
Обратите внимание, что стиль 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 ответов
Каждое устройство немного отличается. 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.
Вы не должны отпускать камеру после установки параметров. Я обнаружил, что вспышка активируется (в режиме факела) после того, как я начал предварительный просмотр. (Относится к Motorola Defy, 2.1)
Также рекомендуется проверить поддерживаемые режимы вспышки, прежде чем активировать их.
Неразберимся с настройками камеры на Android - самое темное вуду: многие устройства ведут себя по-разному, и, похоже, нет надежного способа нацелить их всех с помощью одного куска кода. Самый надежный вариант - всегда правильно настраивать камеру при вызове метода onResume(). Я также хотел бы рассмотреть возможность сделать то же самое в onConfigChange (), потому что, по крайней мере, блокировка экрана Motorola может принудительно перевести ваше приложение в портретный режим, перезапустив его полностью.
PS Полагаю, что когда вы закрываете камеру, собственное приложение камеры закрывается, а затем воссоздается в свежем состоянии.
Я сделал это следующим образом, который работает на многих телефонах:
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" />
Это работает для меня на 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();
Вы также можете попытаться добавить вид поверхности. Посмотрите, пожалуйста, мой ответ на светодиодный фонарик на Galaxy Nexus, которым управляет какой API?
Пожалуйста, используйте эту ссылку:
http://www.androidhive.info/2013/04/android-developing-flashlight-application/
Это очень полезно для меня.
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" />