Manually change widget state from Activity - android

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

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

Related

Widget not updating on creation? - Android

I've got a widget that shows weather when a button is clicked on it. The widget is supposed to do this update when it's first created, however that's not the case. I have to manually click-update it once I put it on homescreen.
Q. How to I update the widget automatically once it's created?
Things I've tried:
Use onEnabled inside Widget Provider
Use onRecieve inside Widget Provider
My WidgetProvider:
public class Widget extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.rButton, buildButtonPendingIntent(context));
pushWidgetUpdate(context, views);
}
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.setAction("update");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void pushWidgetUpdate(Context context, RemoteViews views) {
ComponentName myWidget = new ComponentName(context, Widget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, views);
}
}
My BroadcastReceiver:
public class WidgetReceiver extends BroadcastReceiver {
double lat, lon;
String xtemp, xmaxtemp, xmintemp, xcity, xweather, provider, weatherpic;
Location loc;
LocationManager mlocManager;
//======================================= OnReceive Method
#Override
public void onReceive(Context context, Intent intent) {
try {
if (intent.getAction().equals("update")) {
new MyAsyncTask2().execute(context);
}
} catch (Exception e){
e.printStackTrace();
}
}
public class MyAsyncTask2 extends AsyncTask<Context, Void, String> {
//Does all the update for the weather and shows it on the textViews
}
}
I'm new to Widget programming, let me know if I can make any optimizations! :)

Automatically update widget in the home screen when i make modification in my application

How can we updating the View of a Home Screen Widget on the onReceive method of AppWidgetProvider?.I am trying to update the listview of my Home screen widget but it seems that I cant access the listview of my AppWidgetProvider on onReceive method.My problem is when i changes in my application and come back to the home screen that the widget has no modification.Here is a sample code of my onReceive
public class WidgetTaskSchedular extends AppWidgetProvider {
private final String TAG = "CalendarViewSample:"
+ this.getClass().getName();
static int ID;
int[] sameid=new int[1];
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(intent.getAction().equals("update_widget"))
{
Log.i(TAG,"AppWidgetIds:"+ID);
for(int i=0;i<1;i++)
{
sameid[i]=ID;
Log.i(TAG,"SameId:"+sameid[i]);
onUpdate(context, AppWidgetManager.getInstance(context),sameid);
}
}
}
public static String EXTRA_WORD=
"com.capsone.testing.calendar.WORD";
#SuppressWarnings("deprecation")
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i=0; i<appWidgetIds.length; i++) {
ID=appWidgetIds[i];
Log.i(TAG,"LengthofWidget:"+appWidgetIds.length);
Log.i(TAG,"TestAppWidget:"+appWidgetIds[i]);
Intent intentWidgetService=new Intent(context, WidgetService.class);
intentWidgetService.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intentWidgetService.setData(Uri.parse(intentWidgetService.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews remoteView=new RemoteViews(context.getPackageName(),
R.layout.widgetlayout);
remoteView.setRemoteAdapter(appWidgetIds[i], R.id.listWidget,
intentWidgetService);
Intent clickIntent=new Intent(context, ActionBarActivity.class);
PendingIntent clickPendingIntent=PendingIntent
.getActivity(context, 0,
clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setPendingIntentTemplate(R.id.listWidget, clickPendingIntent);
ComponentName component=new ComponentName(context,WidgetTaskSchedular.class);
appWidgetManager.updateAppWidget(component, remoteView);
}
}
}
MainActivity class:
In this main class i change some modification and broadcast this to widget class using on pause method:
#Override
public void onPause() {
super.onPause();
Intent updateWidget = new Intent(getActivity(), WidgetTaskSchedular.class);
updateWidget.setAction("update_widget");
PendingIntent pending = PendingIntent.getBroadcast(getActivity(), 0, updateWidget, PendingIntent.FLAG_CANCEL_CURRENT);
try {
pending.send();
} catch (CanceledException e) {
e.printStackTrace();
}
}

Start my application by clicking on widget

I'm trying How do I run an Activity from a button on a widget in Android? in order to launch my application on click on an image button. When i un-comment the code it switches the images but when i try to use this code it does nothing. I'd like to kick off my application instead.
public class MyWidgetIntentReceiver extends BroadcastReceiver {
private static int clickCount = 0;
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("pl.looksok.intent.action.CHANGE_PICTURE")){
updateWidgetPictureAndButtonListener(context);
}
}
private void updateWidgetPictureAndButtonListener(Context context) {
Log.i("PROJECTCARUSO", "updateWidgetPictureAndButtonListener");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
// remoteViews.setImageViewResource(R.id.widget_button, getImageToSet());
//
// //REMEMBER TO ALWAYS REFRESH YOUR BUTTON CLICK LISTENERS!!!
// remoteViews.setOnClickPendingIntent(R.id.widget_button, MyWidgetProvider.buildButtonPendingIntent(context));
//
// MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
Intent intentClick = new Intent(context, FragmentChange.class);
PendingIntent pendingIntent = PendingIntent.getActivity (context, 0,
intentClick, 0);
remoteViews.setOnClickPendingIntent (R.id.widget_button, pendingIntent);
}
private int getImageToSet() {
clickCount++;
return clickCount % 2 == 0 ? R.drawable.app_icon : R.drawable.energy;
}
}
Here's what i finally got to work:
public class WidgetProvider extends AppWidgetProvider {
public static String SWITCH_WIDGET_UPDATE = "MainActivity.Switch";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.i("PROJECTCARUSO","onUpdate");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
remoteViews.setOnClickPendingIntent(R.id.widget_button, buildButtonPendingIntent(context));
Intent intentClick = new Intent(context, FragmentChange.class);
PendingIntent pendingIntent = PendingIntent.getActivity (context, 0, intentClick, 0);
remoteViews.setOnClickPendingIntent (R.id.widget_button, pendingIntent);
pushWidgetUpdate(context, remoteViews);
}
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.setAction("CHANGE_PICTURE");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, WidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
}
}

Cant change ImageView resource on RemoteView Android

I'm trying yo make a simple widget with clickable image that will change when its clicked.
I don't understand why it doesn't work
public class AppWidget extends AppWidgetProvider {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction()==null) {
context.startService(new Intent(context,
ToggleService.class));
} else {
super.onReceive(context, intent);
}
}
#Override
public void onUpdate(Context context, AppWidgetManager
appWidgetManager, int[] appWidgetIds) {
context.startService(new Intent(context,
ToggleService.class));
}
public static class ToggleService extends IntentService {
public ToggleService() {
super("AppWidget$ToggleService");
}
#Override
protected void onHandleIntent(Intent intent) {
ComponentName me=new ComponentName(this, AppWidget.class);
AppWidgetManager mgr=AppWidgetManager.getInstance(this);
mgr.updateAppWidget(me, buildUpdate(this));
}
private RemoteViews buildUpdate(Context context) {
RemoteViews updateViews=new
RemoteViews(context.getPackageName(),R.layout.widget);
int a = 1;
if(a ==
1) {
updateViews.setImageViewResource(R.id.phoneState,
R.drawable.dual_off);
} else {
updateViews.setImageViewResource(R.id.phoneState,
R.drawable.dual_on);
}
Intent i=new Intent(this, AppWidget.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i,0);
updateViews.setOnClickPendingIntent(R.id.phoneState,pi);
return updateViews;
}
}
}
I have tried all sort of things in for loop but it just won't change image.
I have done this from a book about android development, am new to java and android.
You would to update your widget by AppWidgetManager, after changing remoteview's source.In this snippet code I try to change layout of widget that it's AppWidgetProvider name is DictionWidgetProvider :
private void hideWidgetInstances() {
hideViews = new RemoteViews(App.getContext().getPackageName(),
R.layout.hide);
AppWidgetManager mManager = AppWidgetManager.getInstance(App
.getContext());
ComponentName cn = new ComponentName(App.getContext(),
DictionWidgetProvider.class);
mManager.updateAppWidget(cn, hideViews);
}
Here App is a class that extends Application.You can use Application Context to reach ComponentName.

TextView Widget Not Updating

My TextView Widget is not updating on the home screen.
The new value of the text does not appear on the widget but the old value still remains as it was. This is my code for the widget class and activity that calls the widget update:
public class MotivappWidget extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Intent intent = new Intent(context, ViewAll.class);
PendingIntent pending = PendingIntent
.getActivity(context, 0, intent, 0);
RemoteViews updateViews = new RemoteViews(context.getPackageName(),
R.layout.widget);
// updateViews.setTextViewText(R.id.widget_text, input);
updateViews.setOnClickPendingIntent(R.id.widget_text, pending);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
}
public class ViewAll extends Activity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_view);
}
protected void onResume() {
super.onResume();
updateWidgetText();
}
private void updateWidgetText() {
LayoutInflater inflater = (LayoutInflater) getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View vi_widgy = inflater.inflate(R.layout.widget, null); //there is a layout xml file called widget.xml already made
TextView tv_widgy = (TextView) vi_widgy.findViewById(R.id.widget_text); //in widget.xml, there is a text view called widget_text
tv_widgy.setText("Text has just changed."); //this text never appears on the widget home even after updating
updateAllWidgets();
}
private void updateAllWidgets(){
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(this, MotivappWidget.class));
if (appWidgetIds.length > 0) {
new MotivappWidget().onUpdate(this, appWidgetManager, appWidgetIds);
}
}
}

Categories

Resources