小工具手电筒

时间:2016-02-15 16:48:44

标签: android widget broadcastreceiver flashlight

我想创建一个小工具来打开/关闭手电筒,这就是我所做的:

小部件类:

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

我的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>

问题是,当我在小部件布局上单击此ImageView时,它会打开手电筒,但当我想将其关闭时,它会崩溃(“抱歉,但应用程序已停止...”消息)。

我在做什么?

1 个答案:

答案 0 :(得分:1)

您没有说明实际的错误消息,但我在第二次按下小部件时遇到了崩溃。我看到了:
java.lang.RuntimeException: Fail to connect to camera service
它看起来像你的问题是因为isLightOn总是假的,所以你的代码试图重新打开已经打开的相机。要解决此特定问题,请将isLightOn设为静态,如下所示:
private static boolean isLightOn = false;