How to add activity button in Android widget - android

This is the first time that I need to create an home widget for android.
I need to define buttons in my widget_layout to launch some activities so I have created a class WidgetProvider that extends AppWidgetProvider and shows the Widget in the Home, but I have noticed that there isn't onCreate, so I haven't understod how to exactly link the button in my layout xml with a listener that can open the desired activity.
There are many widget on the market that have buttons of this kind.
how should I do?

In widgets you have to use RemoteViews instead of View, and there is no findViewById(), and therefore no setOnClickListener(). What you can do however is use remoteViews.setOnClickPendingIntent(id, pendingIntent). Here's a minimal way to open the activity using this:
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int i = 0; i < appWidgetIds.length; i++) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent appIntent = new Intent(context, MyActivity.class);
appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent appPendingIntent = PendingIntent.getActivity(context, REQUEST_CODE, appIntent, PendingIntent.FLAG_CANCEL_CURRENT);
views.setOnClickPendingIntent(R.id.widget_button, appPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds[i], views);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}

Related

Changing Widget Image by OnClick (or PendingIntent ?)

I would like my Appwidget in addition to the main function nor (Widget)images changed.
When calling the function PendingIntent pendingIntent = PendingIntent.getActivity(context, 1001, new Intent(context, Counter.class), 0); should also change the widget to the new image.
Then, when the requested activity exits, the widget will switch to the old image. The Counter.class itself has no layout - so I can still see the homescreen with the widget when activity is running. Why would that the widget displays through changing the picture that the activity is running or rather not.
But I have no idea how to do it.
My WidgetProvider code:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = appWidgetIds.length; --i >= 0;) {
int appWidgetId = appWidgetIds[i];
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context, Counter.class), 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.count_widget);
remoteViews.setOnClickPendingIntent(R.id.countWidget, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
P.S. Sorry for my English :)

Open an activity inside a widget

I know how to open an activity from a widget. It will open full screen.
Is it possible to open one inside a widget?
My activity is part of an application, it has a large code. The activity opens a camera and runs some algorithms. Can I have a 4x4 widget, and run the activity inside the widget with the algorithms of my project? (Basically a shortcut to the activity, but playing inside the widget).
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, ClassToLaunch.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
views.setOnClickPendingIntent(R.id.widget_id, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
You cannot do this but you can make the best use of your layout and its updating intervals as widgets has its own life cycle.
Do not use Activity and use Fragment. It can do everything the Activity does (if can call methods of parent activity if these are needed) and also can be planted into dedicated part of the screen.

App widget button to trigger onUpdate

public class ExampleAppWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this
// provider
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.example_appwidget);
Intent intent = new Intent(context, Fragment_testActivity.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.button1, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app
// widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
Why doesn't the button1 trigger onUpdate (nor onReceive) when the widget is added to the homescreen and button1 is clicked? Adding/removing the widget triggers those events, but not clicking the button.
Manifest, widget declaration, widget layout declaration
First thing I see:
new Intent(context, Fragment_testActivity.class);
You specify an activity as the receiving component. The activity has nothing to do with the update process. Try to set ExampleAppWidgetProvider as the component of the intent or don't specify a component at all (e.g. by using new Intent()).

Android widget button unclickable when adding more than one widget

I have a widget which is basically a big button (with some images in the background). The button works fine if there's just one widget on the home screen (or more than one after a phone reboot), but if I try to add another widget, the button suddenly stops reacting (on the second widget).
Been struggling with this for months now. Hopefully you'll be able to assist.
public class StatsWidget extends AppWidgetProvider {
public static String ACTIONWIDGETCLICK = "MyWidgetClick";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Intent intentt = new Intent(context, StatsService.class);
context.startService(intentt);
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
Intent intent = new Intent(context, StatsWidgetActivity.class);
intent.setAction(ACTIONWIDGETCLICK);
intent.putExtra("widgetId", appWidgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
The only error I see in your code is you forgot to add
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
This must be used when starting an Activity from a service/broadcastreciever/etc. Otherwise are you updating the widget from anywhere else in your app? I recently had a problem with the pending intent unresistering itself because I updated the widget from within my app and didn't add the
views.setOnClickPendingIntent(R.id.widget_button, pendingIntent);
to the update code.
Hope this helps

Launching activity from widget fail after sometimes

I have implemented a App Widget to launch my activity when clicked.
onUpdate() method of WidgetProvider:
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.mywidgetprovider_layout);
// ....update updateViews here
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
Intent onClickedIntent = new Intent(context,MyActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0, onClickedIntent, 0);
updateViews.setOnClickPendingIntent(R.id.myView, pi);
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
}
}
It work as expected after the widget added on home screen.
But after sometimes, it cannot launch the activity again! I have to remove the widget and add again.
How can I fix it? please help.
I'd do it like this:
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.mywidgetprovider_layout);
Intent onClickedIntent = new Intent(context,MyActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0, onClickedIntent, 0);
updateViews.setOnClickPendingIntent(R.id.myView, pi);
for (int i=0; i<appWidgetIds.length; i++) {
appWidgetManager.updateAppWidget(appWidgetIds[i], updateViews);
}
}
One thing I'm not sure on is the call to super.onUpdate(). My own widget code doesn't have it and seems to work fine... not sure if it's needed or not.
I don't know if this refactor will fix your issue though!
I know this is like two years late but I struggled with this too until today when I think I know what I was doing wrong. I think the main key is to focus on the use of the RemoteViews class. You prepare these objects as a sort of instruction set for a another process to follow. Setting the "on click pending intent" must done before sending it to the updateAppWidget method, so your first call to that method won't prime your "myView" object for clicks. Your code next sets the onClick trigger and calls updateAppWidget a second time. It looks like that one should work but there is a whole confusing subject regarding just when two intents are distinct or ambiguous which you may want to read about to understand why your code is working unpredictably. If I'm right, the take-away is to simply not call updateAppWidget the first time and then always make sure to set your onClick trigger whenever creating RemoteViews objects. I hope so anyway.

Categories

Resources