1

I am trying to make a flash light widget for the galaxy nexus and have been stuck on this problem FOR DAYS. I have a widget that consists of a button that functions like a toggle. But I can't get the button to turn on the flash. The widget works as a toggle using toasts, but once I add the lines of code that communicate with the flash it crashes. So if you only left the toast code in each if statement, then the toasts would work. I know I am supposed to be using SurfaceHolder.Callback but I dont know how to implement that on a class that extends AppWidgetProvider. If someone could please look over my code and try to help me make this widget I would be very grateful. I just don't know how to implement this with the appwidgetprovider class.

This error comes up only when I have:

//TURN FLASH OFF
Parameters p = cam.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_OFF);
cam.setParameters(p);
cam.stopPreview();

and:

//TURN FLASH ON
Parameters p = cam.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);                    
cam.setParameters(p);
cam.startPreview();

If I dont put these lines of code in, the widget runs with no errors and only displays the toasts. Meaning it accesses the onReceive() method.

I am using a galaxy nexus.

public class FlashWidget extends AppWidgetProvider {

Camera cam;
RemoteViews view;
private static final String ACTION_WIDGET_RECEIVER = "Action";
private static boolean isLightOn = false;



 @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

        final int n = appWidgetIds.length;
        view = new RemoteViews(context.getPackageName(), R.layout.widget_lay);

        for (int i = 0; i < n; i++) {  
               int appWidgetId = appWidgetIds[i];  

               Intent intent = new Intent(context, FlashWidget.class);
               intent.setAction(ACTION_WIDGET_RECEIVER);

               PendingIntent pend = PendingIntent.getBroadcast(context, 0, intent, 0);

               view.setOnClickPendingIntent(R.id.button1, pend);


               appWidgetManager.updateAppWidget(appWidgetId, view);
        }


    }

    @Override
    public void onReceive(Context context, Intent intent) {

        String action =intent.getAction();

        if(intent.getAction().equals(action)) {


            //YES ITS ON, so turn it OFF
            if(isLightOn) {

                isLightOn = false;
                //TURN FLASH OFF
                Parameters p = cam.getParameters();
                p.setFlashMode(Parameters.FLASH_MODE_OFF);
                cam.setParameters(p);
                cam.stopPreview();
                Toast.makeText(context, "Flash OFF", Toast.LENGTH_SHORT).show();

            //NO ITS OFF, SO LETS TURN IT ON
            } else {

                isLightOn = true;
                //TURN FLASH ON
                Parameters p = cam.getParameters();
                p.setFlashMode(Parameters.FLASH_MODE_TORCH);

                cam.setParameters(p);
                cam.startPreview();
                Toast.makeText(context, "Flash ON", Toast.LENGTH_SHORT).show();

            }

            super.onReceive(context, intent);

        }


    } 
}

AndroidManifest.xml

<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />

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



<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.flash.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver 
        android:name=".FlashWidget"
        android:label="Flash">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
            <action android:name="com.example.flash.ACTION_WIDGET_RECEIVER"/>
            <action android:name="android.appwidget.action.APPWIDGET_ENABLED"/>
        </intent-filter>
        <meta-data 
            android:name="android.appwidget.provider"
            android:resource="@xml/widget_in"/>
   </receiver>
</application>

</manifest>

And this is the error I get when I try to put the widget on my home screen

E/AndroidRuntime(10346): FATAL EXCEPTION: main
E/AndroidRuntime(10346): java.lang.RuntimeException: Unable to start receiver com.example.flash.FlashWidget: java.lang.NullPointerException
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2236)
E/AndroidRuntime(10346): at android.app.ActivityThread.access$1500(ActivityThread.java:130)
E/AndroidRuntime(10346): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1271)
flash
  • 265
  • 4
  • 15
  • Please have a look at my answer here http://stackoverflow.com/questions/7515309/widget-for-turning-on-off-camera-flashlight-in-android – Kartik Domadiya Mar 12 '13 at 05:23

3 Answers3

0

you have to put some condition in manifest.xml file

<receiver
        android:name=".FlashWidget "
        android:label="FlashLight">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>            
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/your xml file" />
    </receiver>

IF you find any trouble then let me know.

Harshid
  • 5,701
  • 4
  • 37
  • 50
  • I have this in my manifest, that is how I access my onReceive function. – flash Mar 12 '13 at 05:09
  • @flash onReceive() call or not? – Harshid Mar 12 '13 at 05:13
  • I just uploaded my manifest, I'm not sure what you are asking. Can you please be more specific? Thank you for your help – flash Mar 12 '13 at 05:20
  • I have exactly what you have in your answer, and I am still getting the error. My problem is in turning the camera on and off. – flash Mar 12 '13 at 05:32
  • Oh I'm sorry, I just saw your link to a similar question. I will give it a shot. Thank you – flash Mar 12 '13 at 05:34
  • http://stackoverflow.com/questions/15038385/how-to-create-android-app-with-app-widget-in-single-application see this. – Harshid Mar 12 '13 at 05:37
  • well this is really weird. I just did what was done in the link you sent me, and it did not work on my galaxy nexus. but I tried it on my Nexus 4 and worked fine. But when I ran the application on the galaxy nexus, I got a warning (I believe) in the log, it was highlighted in yellow. and it said "Fail to connect to camera service". – flash Mar 12 '13 at 06:11
  • @flash may be problem of any flash light,tourch light etc. – Harshid Mar 12 '13 at 06:19
  • thats weird, because it works within a normal activity, but doesnt work from the widget on the galaxy nexus. Either way, thank you for your help. – flash Mar 12 '13 at 06:21
0
Add camera.open();
if(isLightOn){           
        Log.i("info", "torch is turned off!");
        parameter.setFlashMode(Parameters.FLASH_MODE_OFF);
        Global.camera.setParameters(parameter);
        ibtnSwith.setBackgroundResource(R.drawable.switch_off);
        isLightOn = false;


    } else {
        parameter.setFlashMode(Parameters.FLASH_MODE_TORCH);
        Global.camera.setParameters(parameter);                 
        isLightOn = true;
        ibtnSwith.setBackgroundResource(R.drawable.switch_on);
        playsound();
        Log.i("Home.java", "Torch is turned on!");  
    }
Sanu
  • 455
  • 1
  • 6
  • 17
0

In nexus devices it should add a dump surface to make the flash work, i was searching for a long time that i tried every code in internet but the flash did not turn on, a last i found the solution as follows:

private void turnLEDOn() 
{
    // In order to work, the camera needs a surface to turn on.
    // Here I pass it a dummy Surface Texture to make it happy.
    camera = Camera.open();
    camera.setPreviewTexture(new SurfaceTexture(0));
    camera.startPreview();
    Parameters p = camera.getParameters();
    p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
    camera.setParameters(p);`enter code here`
}

private void turnLEDOff()
{
    if (camera != null)
    {
        // Stopping the camera is enough to turn off the LED
        camera.stopPreview();
        camera.release();
        camera = null;
    } else
        throw new NullPointerException("Camera doesn't exist to turn off.");

}
MJBLACKEND
  • 121
  • 1
  • 3