Krzysztof Majewski
Krzysztof Majewski

Reputation: 2534

Widget Flashlight

I want to create a widget for turning on/off the flashlight and this is What I did:

Widget class:

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

My BroadcastReceiver:

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

}

AndroidManifest:

<?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>

The problem is when I click this ImageView on widget layout it switches on the flashlight but when I want to switch it off it crashes ("sorry but app was stopped..." message).

What am I doing wong?

Upvotes: 0

Views: 421

Answers (1)

RickBoyerDev
RickBoyerDev

Reputation: 2109

You don't state the actual error message but I am getting a crash when pressing the widget a 2nd time as well. I'm seeing:
java.lang.RuntimeException: Fail to connect to camera service
It looks to me like your problem is because isLightOn is always false, so your code is attempting to re-open the already open camera. To fix this specific issue, make isLightOn static, like this:
private static boolean isLightOn = false;

Upvotes: 1

Related Questions