I am working on an android app with a Widget.
Everything works fine except for one thing.
I debug and code my app on different computers so when I launch the app for the first time i need to reinstall it because of the different debug key. When I try readding my widget after the installation I get the 'problem loading widget' and I need to reboot my phone to get it to work again.
This does not always happen, there are also other strange things that might happen.
My widget name, in the add widget list screen, gets renamed to 'foo.packagename.WidgetName' instead of the Widget Title.
The Widget icon gets replaced by the default android launcher icon
When I try adding the widget and place it on the homescreen, the previewimage gets replaced by a random icon
Beta testers experience the same problems after an update, even with the same key (release version).
Is this an android issue, or is something wrong in my code?
My AppWidgetProvider (partially)
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final int N = appWidgetIds.length;
SimpleDateFormat fmt = new SimpleDateFormat("EEEE d MMMM");
String date = fmt.format(new Date());
for (int i = 0; i < N; i++) {
RemoteViews remoteViews = updateWidgetListView(context,
appWidgetIds[i], date);
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds[i], R.id.list);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
#Override
public void onDisabled(Context context) {
Intent intent = new Intent(context, AppService.class);
intent.setAction(AppService.ACTION_UPDATE_WIDGET);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
super.onDisabled(context);
}
private RemoteViews updateWidgetListView(Context context, int appWidgetId, String date) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget);
Intent svcIntent = new Intent(context, ListWidgetService.class);
remoteViews.setRemoteAdapter(R.id.list, svcIntent);
remoteViews.setEmptyView(R.id.list, R.id.empty_view);
remoteViews.setTextViewText(R.id.widget_sub_title, date);
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.widget_root, pendingIntent);
return remoteViews;
}
widget_provider.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dp"
android:minHeight="110dp"
android:previewImage="#drawable/ic_launcher"
android:initialLayout="#layout/widget"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="0">
Related
My widget provider has intent with value named id, wchich is equal current day of year. But this intent does not change. If today it is focused on 8th March, tomorrow it will also be focused on this day. And on the next day also and so on. But I need to refresh this intent every day.
MyWidgetProvider.java:
public class MyWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
int layoutId = R.layout.widget;
Calendar c = Calendar.getInstance();
c.setTime(new Date());
int id = c.get(Calendar.DAY_OF_YEAR);
boolean leap = new GregorianCalendar().isLeapYear(c.get(Calendar.YEAR));
int targetId = id<60?id:id+(leap?0:1);
for (int i:appWidgetIds) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("from", "widget");
intent.putExtra("id", targetId);
intent.putExtra("widgetID", i);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), layoutId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.widget_relative_main, pendingIntent);
}
}
}
my_widget_provider.xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="#layout/widget"
android:minHeight="31dp"
android:minWidth="72dp"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="300000" >
</appwidget-provider>
What is a problem?
SOLUTION:
There was required PendingIntent flag "FLAG_UPDATE_CURRENT":
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
And everything works well!
Intent intent = new Intent( context, ColorConfigure.class);
Intent.putExtras(AppWidgetManager.EXTRA_APPWIDGET_ID, appwidgetId );
PendingIntent pi = PendingIntent.getActivity( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews r = new RemoteViews( context.getPackageName(), R.layout. activity_widget);
r.setOnClickPendingIntent(R.I'd.pic, pic);
The above code isn't working for the time i.e., when I start the widget for the first time then widget gets loaded easily but when I go onto start a new activity from the widget then nothing happens.
But whenever I re-run my app from the eclipse without removing the widget then my widget starts running successfully without any glitch.
I don't really know what sort of problem is this one?? Or if anyone is able to help me by sending me the code of a widget that start a fresh activity from a button on that activity.
even i have faced similar problem for my app homescreen widget .which is very similar to fb/twitter homescreen widget(show updates if not signed show as "your not signedin").achieved using android service. even you don't need a service. in your case you are not calling manager.updateAppWidget(ids, views);
public class NFWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final Intent intent = new Intent(context, UpdateService.class);
context.startService(intent);
}
}
Updateservice.class
//my app code..mention service class app manifest
public void onStart(Intent intent, int startId) {
AppWidgetManager manager = AppWidgetManager.getInstance(this);
ComponentName thisWidget = new ComponentName(this,
NFWidgetProvider.class);
int[] ids = manager.getAppWidgetIds(thisWidget);
final int N = ids.length;
for (int i = 0; i < N; i++) {
int awID = ids[i];
RemoteViews views = new RemoteViews(getPackageName(),
R.layout.widget_layout);
Intent intent = new Intent(this, your intented class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//views.setTextViewText(R.id.widgetcount, visitstext);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, intent, 0);
views.setOnClickPendingIntent(R.id.widgetimage, pendingIntent);
manager.updateAppWidget(awID, views);
}
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 :)
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
i have a widget to my application that is refreshed every 10 sec. If i change the language of the phone, the widget stops working. I mean, the textviews do not load the texts until they are refreshed (so after 10sec). I added a functionality that the user can open the app by clicking on the widget (an ImageView). This problem still stays.
This whole problem appears also when I restart the phone. I have to wait 10 secs for the textviews to load the texts, but I cannot click on the widget. I may change this interval to 1 sec, what would solve this issue (making it almost invisible for the user). But like I said, I still cannot click on the widget.
Here is the full AppWidgetProvider class:
public class HelloWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_CONFIGURE = "ConfigureWidget";
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
private static final int REQUEST_CODE_ONE = 10;
String elso;
public static String MY_WIDGET_UPDATE = "MY_OWN_WIDGET_UPDATE";
#Override
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];
updateAppWidget(context, appWidgetManager, appWidgetId);
Toast.makeText(context, "onUpdate(): " + String.valueOf(i) + " : " + String.valueOf(appWidgetId), Toast.LENGTH_SHORT).show();
}
Intent intent = new Intent(context, UpdateService.class);
context.startService(intent);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
Intent configIntent = new Intent(context, MainActivity.class);
configIntent.setAction(ACTION_WIDGET_CONFIGURE);
PendingIntent configPendingIntent = PendingIntent.getActivity(context, REQUEST_CODE_ONE, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.ImageView01, configPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
Intent myIntent = new Intent(context, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTimeInMillis(System.currentTimeMillis());
calendar2.add(Calendar.SECOND, 1);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar2.getTimeInMillis(), 50*1000, pendingIntent);
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(MY_WIDGET_UPDATE.equals(intent.getAction())){
Bundle extras = intent.getExtras();
if(extras!=null) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), HelloWidget.class.getName());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
if (appWidgetIds.length > 0) {
new HelloWidget().onUpdate(context, appWidgetManager, appWidgetIds);
}
}
}
}
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId){
}
}
From this code this is the part that serves for opening the MainActivity.class of the app when the user clicks on the widget:
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
Intent configIntent = new Intent(context, MainActivity.class);
configIntent.setAction(ACTION_WIDGET_CONFIGURE);
PendingIntent configPendingIntent = PendingIntent.getActivity(context, REQUEST_CODE_ONE, configIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.ImageView01, configPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
This is the Manfiest part:
<receiver android:name=".HelloWidget" android:label="#string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="#xml/widget_provider" />
</receiver>
And this is the widget_provider.xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="72dip"
android:updatePeriodMillis="86400000"
android:initialLayout="#layout/main"
/>
I have a widget to my application that is refreshed every 10 sec [...]
I may change this interval to 1 sec [...]
In short: That's very bad practice. You should (at maximum) only update every 30 minutes.
By refreshing your Widget every 10 seconds, you kill the battery so fast that nobody will use it. Instead, you could add an "refresh"-button which then manually refreshes the Widget.
Also, in the onUpdate-method, you don't need to call the super-method.
And the onReceive-method does not need to be overridden! The onUpdate-method is automatically called when you use an AppWidgetProvider (not if you use a normal BroadcastReceiver). See here.
Last but not least, you should check if your "call-Activity"-code gets reached and try to debug it with the Log-class. The LogCat-Output might also help solving this.
Can you add this flag
PendingIntent configPendingIntent = PendingIntent.getActivity(context, REQUEST_CODE_ONE, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Also check Logcat for any exception it throws when you click on the widget.