Intereting Posts
Замена драйвера сенсорного экрана в Android-ядре Android 4.4.2 и мягкая клавиатура. Возможноменменю? «Невыполненный метод WebView onKeyDown, вызванный из», произошел Как создавать постоянные аварийные сигналы даже после перезагрузки WebView с 30% фоном в WebViewCoreThread Недопустимый вектор тегов Изменить кнопку андроида: фон для разных доступных Как проверить, установлен ли AlarmManager уже установленный будильник? Maven говорит, что нет плагинов: как их установить? Как отобразить фракции в андроиде? Мои файлы Android XML не могут найти темы ActionBarSherlock Сила Закрыть на регулярном выражении! Отладка собственного кода в android при eclipse не выполняется Не удается разрешить метод 'add (int, com.example.utkarsh.beatle.app.MainActivity.PlaceholderFragment) Выбранный обратный вызов Spinner активируется дважды после вращения, если выбрана ненулевая позиция Как сбросить порядковый номер автоинкремента в sqlite

Виджет для включения / выключения фонарика камеры в Android

Я разрабатываю виджет для включения / выключения камеры водить телефона.

Я создал виджет, который может работать как кнопка переключения (вкл / выкл).

Поведение выглядит следующим образом: иногда светодиодный индикатор остается включенным, когда я включаю виджет. Но он не включает / выключает камеру, но меняет значок.

Я не могу понять, в чем проблема.

То же самое отлично работает в Activity (приложение Torch Light).

Может ли кто-нибудь объяснить мне, как я могу решить свою проблему?

Где я иду не так?

Вы можете посмотреть код ниже, который я сделал до сих пор

onUpdate метод

 @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { //super.onUpdate(context, appWidgetManager, appWidgetIds); remoteViews = new RemoteViews( context.getPackageName(), R.layout.widgetlayout); watchWidget = new ComponentName( context, FlashLightWidget.class ); Intent intentClick = new Intent(context,FlashLightWidget.class); intentClick.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, ""+appWidgetIds[0]); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetIds[0],intentClick, 0); remoteViews.setOnClickPendingIntent(R.id.myToggleWidget, pendingIntent); appWidgetManager.updateAppWidget( watchWidget, remoteViews ); ctx=context; } 

Метод onReceive выглядит следующим образом:

 @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub remoteViews = new RemoteViews( context.getPackageName(), R.layout.widgetlayout); if (intent.getAction()==null) { Bundle extras = intent.getExtras(); if(extras!=null) { if(status) { status=false; remoteViews.setImageViewResource(R.id.myToggleWidget, R.drawable.shutdown1); processOnClick(); Toast.makeText(context,"Status==false-onclick",Toast.LENGTH_SHORT).show(); } else { status = true; remoteViews.setImageViewResource(R.id.myToggleWidget, R.drawable.shutdown2); processOffClick(); Toast.makeText(context,"Status==true--Ofclick",Toast.LENGTH_SHORT).show(); } } watchWidget = new ComponentName( context, FlashLightWidget.class ); (AppWidgetManager.getInstance(context)).updateAppWidget( watchWidget, remoteViews ); } } } 

Метод processOffClick

 private void processOffClick() { if (mCamera != null) { mCamera.stopPreview(); mCamera.setPreviewCallback(null); mCamera.release(); mCamera = null; } } 

Метод processOnClick

 private void processOnClick() { if(mCamera==null) { try { mCamera = Camera.open(); } catch (Exception e) { e.printStackTrace(); } } if (mCamera != null) { Parameters params = mCamera.getParameters(); List<String> flashModes = params.getSupportedFlashModes(); if (flashModes == null) { return; } else { 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 if (mCamera == null) { //Toast.makeText(ctx, "Camera not found", Toast.LENGTH_LONG).show(); return; } } 

Solutions Collecting From Web of "Виджет для включения / выключения фонарика камеры в Android"

После долгого времени я получил разрешение решить эту проблему.

Вот что я сделал.

Класс FlashlightWidgetProvider :

 public class FlashlightWidgetProvider extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Intent receiver = new Intent(context, FlashlightWidgetReceiver.class); receiver.setAction("COM_FLASHLIGHT"); receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); views.setOnClickPendingIntent(R.id.button, pendingIntent); appWidgetManager.updateAppWidget(appWidgetIds, views); } } 

И BroadcastReceiver для FlashlightWidgetReceiver:

 public class FlashlightWidgetReceiver extends BroadcastReceiver { private static boolean isLightOn = false; private static Camera camera; @Override public void onReceive(Context context, Intent intent) { RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); if(isLightOn) { views.setImageViewResource(R.id.button, R.drawable.off); } else { views.setImageViewResource(R.id.button, R.drawable.on); } AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); appWidgetManager.updateAppWidget(new ComponentName(context, FlashlightWidgetProvider.class), views); if (isLightOn) { if (camera != null) { camera.stopPreview(); camera.release(); camera = null; isLightOn = false; } } else { // Open the default ie the first rear facing camera. camera = Camera.open(); if(camera == null) { Toast.makeText(context, R.string.no_camera, Toast.LENGTH_SHORT).show(); } else { // Set the torch flash mode Parameters param = camera.getParameters(); param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); try { camera.setParameters(param); camera.startPreview(); isLightOn = true; } catch (Exception e) { Toast.makeText(context, R.string.no_flash, Toast.LENGTH_SHORT).show(); } } } } } 

Требуется разрешение в файле Manifest.xml :

 <uses-permission android:name="android.permission.CAMERA"></uses-permission> 

Также регистрируйте приемники в файле Manifest.xml :

 <receiver android:name=".FlashlightWidgetProvider" android:icon="@drawable/on" android:label="@string/app_name"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/flashlight_appwidget_info" /> </receiver> <receiver android:name="FlashlightWidgetReceiver"> <intent-filter> <action android:name="COM_FLASHLIGHT"></action> </intent-filter> </receiver> 

Важное примечание . Этот код работает идеально, если ваш телефон поддерживает FLASH_MODE_TORCH .

Я тестировал в Samsung Galaxy Ace 2.2.1 и 2.3.3. Код не работает, потому что у этого устройства нет FLASH_MODE_TORCH.

Работает отлично в HTC Salsa, Wildfire ..

Если кто-то может протестировать и опубликовать результаты здесь, было бы лучше.

Лучший способ обработки кликов из RemoteViews – создать PendingIntent который вызывает службу, и выполнить «материал», который вы хотите в службе, включая любые дополнительные обновления RemoteViews для вашего виджета. Вы можете отправить соответствующие данные в дополнительные задания. Служба вызывает stopSelf() в конце, поэтому она отключается.

Вы не можете поддерживать какое-либо состояние в BroadcastReceiver ; Система запускает их в любом доступном потоке и не поддерживает ссылки на ваш экземпляр после вызова onReceive() . mCamera гарантировать, что mCamera переменная mCamera поддерживается между вызовами вашего BroadcastReceiver .

Если вам действительно нужно поддерживать состояние, вы должны сделать это в службе и не использовать stopSelf() (до соответствующего времени).

Вам не нужен поток пользовательского интерфейса для использования класса Camera , если вы не делаете предварительный просмотр изображения, для чего требуется SurfaceHolder (и подразумевает пользовательский интерфейс). Однако вы должны активировать цикл событий, или Camera не будет отправлять вам обратные вызовы, что является проблемой, поскольку Camera в основном асинхронна. Вы можете сделать это в службе (см. HandlerThread ) и поддерживать свою службу до тех пор, пока не приступит к release() . Какой бы Camera.open() ни Camera.open() будут получать обратные вызовы.

Все ли на самом деле читали раздел о виджетах приложений? http://developer.android.com/guide/topics/appwidgets/index.html

Использование раздела AppWidgetProvider Class говорит о многом, о чем я говорю здесь.

У меня была аналогичная ситуация, когда мне нужно запустить определенный код android в потоке пользовательского интерфейса … который доступен только в Activity. Мое решение – это действие с полностью прозрачной компоновкой. Таким образом, вы просто видите свой домашний экран (хотя и не отвечаете), пока выполняете свои действия, что в вашем случае должно быть довольно быстрым.

У меня есть одно решение, которое не очень велико, но работает. Попросите виджет вызвать действие, а в действии включите вспышку, а затем закройте Activity. То же самое, чтобы отключить его. Если это работает в Activity, это решение будет работать. Это не изящно, но работает. Я попробовал.