Launching activity from widget fail after sometimes - android

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.

Related

How to add activity button in Android widget

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

Android Widget that can start/stop a service and receive updates every second

I need to create an Android Widget that basically has just a Start/Stop Button and a Field with some information. The Start button should start a service that gets a result every second or so. One part of this result should be displayed in the Widget and the service can be stopped again by pushing the stop button.
Can anyone point me please into the right direction how the strategy to implement this would be?
I've read a lot now, but I am really unsure. From what I understand an AlarmManager would be overkill and drain the Battery really fast or make the phone unresponsive. Also I cant use a BroadcastReceiver since the Service takes more than 5 secs (?? not sure about this).
Any help is appreciated!
First of all it is advisable that while creating the service from widget you should stop it as soon as you do the necessary changes you require as the running service would use battery and memory.
For making widget this would be helpful:-
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId = appWidgetIds[i];
//Give the name of service you want to start in your case Alarm Service
Intent intent = new Intent(context, WidgetService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0,
intent, 0);
//This basically sets the layout of your widget to widget_layout
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
views.setOnClickPendingIntent(R.id.imageView1, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
For your service class you could use stopSelf() in OnStart() methood after doing the changes you require.

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.

Android Widget stops working randomly

I have been working with this problem for three days now and I've looked at every single question on here for an answer. I have a widget with a button on it and all I would like it to do is start a service everytime it is clicked. The problem is that the button stops working randomly. I can't recreate it at all and I have no idea what causes it. My service calls stopSelf(); but I have had this problem with a broadcast receiver also so I believe the problem to be in the widget and not in the service. Here is the code
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
Log.i("Widget", "onUpdate");
final int N = appWidgetIds.length;
for (int i=0; i<N; i++)
{
int appWidgetId = appWidgetIds[i];
Log.i("Widget", "onUpdateLoop");
Intent intent = new Intent(context, ServiceWidgetAction.class);
intent.setAction(Long.toString(System.currentTimeMillis()));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent
.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget);
views.setOnClickPendingIntent(R.id.widgetButton, pendingIntent);
views.setTextViewText(
R.id.widgetTextView,
"Some text");
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
I've checked this code over and over and I have no idea why it is doing this. It does this on 3 separate phones and I can't recreate it. I've tried force stopping the app, clearing it from a task manager adding new widgets etc. to get the widget to stop working and it won't. However when I woke up this morning the widget no longer works. Any help would be GREATLY appreciated.
I ended up figuring out the problem. I was updating the widget from other places in the app and I did not have the complete code for each one. In other words my app updated the textviews in the widget like this
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget);
views.setTextViewText(
R.id.widgetTextView,
"Some text");
appWidgetManager.updateAppWidget(appWidgetId, views);
But it needed the entire code to keep the button registered like this:
Intent intent = new Intent(context, ServiceWidgetAction.class);
intent.setAction(Long.toString(System.currentTimeMillis()));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent
.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget);
views.setOnClickPendingIntent(R.id.widgetButton, pendingIntent);
views.setTextViewText(
R.id.widgetTextView,
"Some text");
appWidgetManager.updateAppWidget(appWidgetId, views);
So bottom line is whenever you update a widget from within your app, make sure it looks exactly like the code in the widget itself. Don't leave anything out.
Did you install your widget into the SD Card?
Google recommends to install all widget, alarm and receiver app types into the internal storage, due system sync problems like this.
Maybe not the solution, but a "must check" ;)
android:installLocation="internalOnly"

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

Categories

Resources