2

My app has a widget that lights the LED Flash when we click on it and swhitch it off when we click again on it.

Here is the code (thanks to Kartik from this post):

WidgetProvider.java

public class WidgetProvider extends AppWidgetProvider {

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

        Intent receiver = new Intent(context, WidgetReceiver.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);

        views.setOnClickPendingIntent(R.id.imageButtonWidget, pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetIds, views);

    }
}

WidgetReceiver.java

public class WidgetReceiver extends BroadcastReceiver {
    public static boolean isLightOn = false;
    public static Camera camera;

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

        if (isLightOn) {
            views.setImageViewResource(R.id.imageButtonWidget,
                    R.drawable.widget_lamp_button_default);
        } else {
            views.setImageViewResource(R.id.imageButtonWidget,
                    R.drawable.widget_lamp_button_checked);
        }


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


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


        } else {
            // Open the default i.e. 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();
                }
            }
        }
    }
}

Now I would like to switch the widget off from inside my app . With this code in the main activity of my app, I can release the camera taken by the widget :

MainActivity.java

//Stop widget camera
        if (WidgetReceiver.isLightOn){
        Camera a = WidgetReceiver.camera;
        a.stopPreview();
        a.release();
        a = null;
        WidgetReceiver.isLightOn=false;}

But the problem is that the widget is still set to the checked drawable (R.drawable.widget_lamp_button_checked). So the FlashLight is well turned off but I still need to force the widget to set its drawable to the unchecked one (R.drawable.widget_lamp_button_default).

How can I do this ?

Edit : Problem Solved

WidgetProvider.java

   public class WidgetProvider extends AppWidgetProvider {

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

             // Set widget's drawable to unchecked

            RemoteViews views2 = new RemoteViews(context.getPackageName(),
                    R.layout.widget);
            AppWidgetManager mManager = AppWidgetManager.getInstance(MainActivity
                    .getContext());
            ComponentName cn = new ComponentName(MainActivity.getContext(),
                    WidgetProvider.class);
            views2.setImageViewResource(R.id.imageButtonWidget,
                    R.drawable.widget_lamp_button_default);
            mManager.updateAppWidget(cn, views2);


            // Widget OnClick Behavior

            Intent receiver = new Intent(context, WidgetReceiver.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);

            views.setOnClickPendingIntent(R.id.imageButtonWidget, pendingIntent);

            appWidgetManager.updateAppWidget(appWidgetIds, views);

        }
    }

WidgetReceiver.java -> kept the same

MainActivity.java

    public class MainActivity extends Activity {
        private static Context mContext;

        public static Context getContext() {
            return mContext;
        }


       @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            mContext = this;


                   //Stop widget camera

                    if (WidgetReceiver.isLightOn){
                    Camera a = WidgetReceiver.camera;
                    a.stopPreview();
                    a.release();
                    a = null;
                    WidgetReceiver.isLightOn=false;}


        // Fire Widget's update with Intent 

        Intent intent = new Intent(this, WidgetProvider.class);
                intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");
                // Use an array and EXTRA_APPWIDGET_IDS instead of
                // AppWidgetManager.EXTRA_APPWIDGET_ID,
                // since it seems the onUpdate() is only fired on that:
                int[] ids = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
                sendBroadcast(intent);

}
Community
  • 1
  • 1
Jecimi
  • 4,113
  • 7
  • 31
  • 40

1 Answers1

0

Send a broadcast to your AppWidgetProvider and update your widget by using updateAppWidget method of AppWidgetManager class,in onReceive() method of AppWidgetProvider:

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


    ...
    views = new RemoteViews(context.getPackageName(),
    R.layout.yourwidgetlayout);
    AppWidgetManager mManager = AppWidgetManager.getInstance(App
    .getContext());
    ComponentName cn = new ComponentName(App.getContext(),
    YourAppWidgetProvider.class);
    //change your views,here I change text of text view witch it's id is "widgettextview" 
    views.setTextViewText(R.id.widgettextview, "lastWord");
    mManager.updateAppWidget(cn, views);
    ...
}     

Here is App definition:

public class App extends Application implements OnInitListener {

    private static Context mContext;

    public void onCreate() {
        super.onCreate();
        mContext = this;
        }
    public static Context getContext() {
        return mContext;
    }
}
hasanghaforian
  • 13,858
  • 11
  • 76
  • 167
  • Sorry, but I don't understand the use of the `App` class. Why use `OnInitListener` which has to do with the `TextToSpeech` api ? – Jecimi Jul 19 '12 at 17:07
  • 1
    Ok, I've solved my problem thanks to your answer, but I didn't use your `App` class but I got the context from my `MainActivity` class (it's maybe what you meant and I didn't understood ?). Anyway, problem solved (see post), thanks for your answer :). – Jecimi Jul 19 '12 at 17:31