Виджет Фонарик

Я хочу создать виджет для включения/выключения фонарика, и вот что я сделал:

Класс виджета:

public class FlashLightWidget extends AppWidgetProvider {

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                                int appWidgetId) {

        Intent receiver = new Intent(context, FlashLightReceiver.class);
        receiver.setAction("NINJA_KRZYSZTOF_FLASHLIGHT");
        receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetId);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0);

        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.flash_light_widget);
        views.setOnClickPendingIntent(R.id.imageView, pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        for (int appWidgetId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }

    @Override
    public void onEnabled(Context context) {
    }

    @Override
    public void onDisabled(Context context) {
    }
}

Мой широковещательный приемник:

public class FlashLightReceiver extends BroadcastReceiver {

    private boolean isLightOn = false;
    private Camera camera;

    @Override
    public void onReceive(Context context, Intent intent) {
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.flash_light_widget);

        if (isLightOn) {
            views.setImageViewResource(R.id.imageView, R.drawable.light_off);
        } else {
            views.setImageViewResource(R.id.imageView, R.drawable.light_on);
        }

        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        appWidgetManager.updateAppWidget(new ComponentName(context, FlashLightWidget.class), views);

        if (isLightOn) {
            if (camera != null) {
                camera.stopPreview();
                camera.release();
                camera = null;
                isLightOn = false;
            }

        } else {
            camera = Camera.open();

            if (camera == null) {
                Toast.makeText(context, "No camera found", Toast.LENGTH_SHORT).show();
            } else {
                Camera.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, "No LED found", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

}

AndroidМанифест:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ninja.majewski.jutswidgetflashlight">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <receiver android:name=".FlashLightWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/flash_light_widget_info" />
        </receiver>

        <receiver android:name=".FlashLightReceiver">
            <intent-filter>
                <action android:name="NINJA_KRZYSZTOF_FLASHLIGHT" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

Проблема в том, что когда я нажимаю этот ImageView на макете виджета, он включает фонарик, но когда я хочу его выключить, он вылетает ("извините, но приложение было остановлено...").

Что я делаю, вонг?


person Krzysztof Majewski    schedule 15.02.2016    source источник


Ответы (1)


Вы не указываете фактическое сообщение об ошибке, но я также получаю сбой при нажатии виджета во второй раз. Я вижу:
java.lang.RuntimeException: Fail to connect to camera service
Мне кажется, ваша проблема в том, что isLightOn всегда имеет значение false, поэтому ваш код пытается повторно открыть уже открытую камеру. Чтобы устранить эту конкретную проблему, сделайте isLightOn статическим, например:
private static boolean isLightOn = false;

person NightSkyDev    schedule 15.02.2016
comment
Большое спасибо :) Мне также пришлось сделать камеру статической. private static Camera camera. - person Krzysztof Majewski; 16.02.2016