I add a configure/settings Activity in my AppWidget and started gotting some problems. At first, I didn't knew what is the cause, so I commented some parts of the code to figure it out. So what I've found is that the AlarmManager code is causing it. I already tried changing simulator's version, cleared the project and everything. I'm dealing with this problem for almost 3 days...
Here are a screen shot showing it. Note that there are 2 widgets in the home screen, completely different, but both are the same! I mean... Both are my AppWidget, they should look as the lower one, but with 2 TextViews... The 2 ImageButtons are there, but they don't always show. :/ http://www.flickr.com/photos/76149280@N08/8169290591/in/photostream? So, my question is: what do I have to do to make it work? Do I have to create a "service", do I have to change same code, even use another thing instead of AlarmManager or what? P.S.: I already asked on Stack Overflow ( http://stackoverflow.com/questions/13322168/alarmmanager-destroying-an-appwidget-android-sdk ), but noting... Here go the codes. * AppProviderInfo (small_widget_provider_info.xml) <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget_layout_small" android:minHeight="40dp" android:minWidth="250dp" android:updatePeriodMillis="86400000" android:configure="com.br.mcsoft.quotes.activity.SettingsActivity" > </appwidget-provider> * AppProvider (WidgetProviderSmall.java) package com.br.mcsoft.quotes.provider; import com.br.mcsoft.quotes.R; import com.br.mcsoft.quotes.Adapters.DBAdapter; import com.br.mcsoft.quotes.activity.QuoteActivity; import com.br.mcsoft.quotes.model.Quote; import android.app.AlarmManager; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.database.SQLException; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.widget.RemoteViews; public class WidgetProviderSmall extends AppWidgetProvider { private static final String TAG = "WidgetProviderSmall"; public static final String URI_SCHEME = "widget_provider_small"; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // super.onUpdate(context, appWidgetManager, appWidgetIds); System.out.println("Updatando..."); final int n = appWidgetIds.length; for (int i = 0; i < n; i++) { System.out.println("Entrou no loop..."); // Cria o RemoteViews RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout_small); // Atualiza os dados... try { DBAdapter db; db = new DBAdapter(context); db.open(); Quote q = db.getRandomQuote(); db.close(); // Guarda o ID da citação... Editor configEditor = context.getSharedPreferences( "QuoteWidgetSmall", 0).edit(); configEditor .putInt(String.format("QuoteId-%d", appWidgetIds[i]), q.getId()); configEditor.commit(); System.out.println("Id: " + appWidgetIds[i]); System.out.println("Quote Id: " + q.getId()); // Verifica o tamanho e trunca o texto da citação... String textQuote = "\"" + q.getQuote() + "\""; if (textQuote.length() > 110 + 10) { textQuote = textQuote.substring(0, 110) + "...\" [...]"; } System.out.println("Quote: " + q.getQuote()); System.out.println("Author: " + q.getAuthor().getName()); // Seta os campos... // rv.setTextViewText(R.id.txtWdgQuote, "\"" + q.getQuote() + // "\""); rv.setTextViewText(R.id.txtWdgQuote, textQuote); rv.setTextViewText(R.id.txtWdgAuthor, "— " + q.getAuthor().getName()); System.out.println("Setou os valores..."); } catch (SQLException e) { Log.e(TAG, e.getMessage(), e); } // Adiciona o listener do evento do botão Next... Intent active = new Intent(context, WidgetProviderSmall.class); active.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); // onUpdate recebe um array de ints, então passa como array. active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { appWidgetIds[i] }); Uri data = Uri.withAppendedPath( Uri.parse(URI_SCHEME + "://widget/id/"), String.valueOf(appWidgetIds[i])); active.setData(data); PendingIntent actionPendingIntent = PendingIntent.getBroadcast( context, appWidgetIds[i], active, 0); rv.setOnClickPendingIntent(R.id.ibtNext, actionPendingIntent); // Adiciona o listener do evento do clique no Widget... active = new Intent(context, WidgetProviderSmall.class); active.setAction(StaticHelper.ACTION_CLICK); // onReceive precisa apenas do Id em um int, então passa assim. active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); data = Uri.withAppendedPath( Uri.parse(URI_SCHEME + "://widget/id/"), String.valueOf(appWidgetIds[i])); active.setData(data); actionPendingIntent = PendingIntent.getBroadcast(context, appWidgetIds[i], active, 0); rv.setOnClickPendingIntent(R.id.laySmall, actionPendingIntent); /* * // Adiciona o listener do evento do botão Settings... active = * new Intent(context, WidgetProviderSmall.class); * active.setAction(StaticHelper.ACTION_SETTINGS); * actionPendingIntent = PendingIntent.getBroadcast(context, 0, * active, 0); rv.setOnClickPendingIntent(R.id.ibtSettings, * actionPendingIntent); */ // Salva tudo appWidgetManager.updateAppWidget(appWidgetIds[i], rv); // Atualiza os dados... } System.out.println("Terminou o update..."); } @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); if (intent.getAction().equals(StaticHelper.ACTION_CLICK)) { Bundle extras = intent.getExtras(); if (extras != null) { int widgetId = extras.getInt( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { // Pega o quote Id SharedPreferences config = context.getSharedPreferences( "QuoteWidgetSmall", 0); int quoteId = config.getInt( String.format("QuoteId-%d", widgetId), -1); System.out.println("Id: " + widgetId); System.out.println("Quote Id: " + quoteId); Intent i = new Intent(context, QuoteActivity.class); Bundle b = new Bundle(); b.putInt("QuoteId", quoteId); i.putExtras(b); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } else { System.out.println("Id ZERADO!"); } } } else if (intent.getAction().equals(StaticHelper.ACTION_SETTINGS)) { // Chama a tela de settings... System.out.println("Chamou o config..."); } } @Override public void onDeleted(Context context, int[] appWidgetIds) { System.out.println("Ih! OnDelete!"); int widgetId; final int n = appWidgetIds.length; for (int i = 0; i < n; i++) { System.out.println("Deletando..."); widgetId = appWidgetIds[i]; Intent widgetUpdate = new Intent(); widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { widgetId }); widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); PendingIntent newPending = PendingIntent.getBroadcast(context, widgetId, widgetUpdate, PendingIntent.FLAG_UPDATE_CURRENT); // Para o alarme... AlarmManager alarms = (AlarmManager) context .getSystemService(Context.ALARM_SERVICE); alarms.cancel(newPending); // Remove o estado armazenado... SharedPreferences config = context.getSharedPreferences( "QuoteWidget", 0); SharedPreferences.Editor edit = config.edit(); edit.remove(String.format("UpdateRate-%d", widgetId)); edit.commit(); System.out.println("Terminou o onDelete"); } super.onDeleted(context, appWidgetIds); } } * Configure Activity (SettingsActivity.java) package com.br.mcsoft.quotes.activity; import com.br.mcsoft.quotes.R; import android.os.Bundle; import android.os.SystemClock; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.RadioGroup; public class SettingsActivity extends Activity implements OnClickListener { private int oldTime = 0; private int newTime; private SharedPreferences config = null; private int widgetId; @Override public void onCreate(Bundle savedInstanceState) { // Inicia a excução... super.onCreate(savedInstanceState); // Chama o layout... setContentView(R.layout.activity_settings); widgetId = 0; // Pega o Id do Widget Intent intent = getIntent(); // new Intent(this, // WidgetProviderSmall.class); Bundle extras = intent.getExtras(); if (extras != null) { widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } else { finish(); return; } // Seta como "cancelar" preventivamente... Intent cancelResultValue = new Intent(); cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); setResult(RESULT_CANCELED, cancelResultValue); // Verifica o tempo atualmente setado config = this.getSharedPreferences("QuoteWidget", 0); try { oldTime = config.getInt(String.format("UpdateRate-%d", widgetId), -1); System.out.println("OldTime: " + oldTime); } catch (Exception e) { e.printStackTrace(); } // O Radio Group... RadioGroup rg = (RadioGroup) findViewById(R.id.radioTime); // Seta o tempo atual no Spinner if (oldTime == 5) { rg.check(R.id.rbtFiveMin); } else if (oldTime == 10) { rg.check(R.id.rbtTenMin); } else if (oldTime == 15) { rg.check(R.id.rbtFifteenMin); } else if (oldTime == 20) { rg.check(R.id.rbtTwentyMin); } else if (oldTime == 30) { rg.check(R.id.rbtThirtyMin); } else if (oldTime == 60) { rg.check(R.id.rbtOneHour); } else if (oldTime == 120) { rg.check(R.id.rbtTwoHours); } // Pega e seta os botões... Button ok = (Button) findViewById(R.id.btnOk); Button cancel = (Button) findViewById(R.id.btnCancel); ok.setOnClickListener(this); cancel.setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // getMenuInflater().inflate(R.menu.activity_settings, menu); return true; } public void onClick(View v) { if (v == (Button) findViewById(R.id.btnOk)) { // Pega o novo tempo de update... RadioGroup rg = (RadioGroup) findViewById(R.id.radioTime); int id = rg.getCheckedRadioButtonId(); if (id == R.id.rbtFiveMin) { newTime = 5; } else if (id == R.id.rbtTenMin) { newTime = 10; } else if (id == R.id.rbtFifteenMin) { newTime = 15; } else if (id == R.id.rbtTwentyMin) { newTime = 20; } else if (id == R.id.rbtThirtyMin) { newTime = 30; } else if (id == R.id.rbtOneHour) { newTime = 60; } else if (id == R.id.rbtTwoHours) { newTime = 120; } if (newTime != oldTime && config != null && widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { System.out.println("newTime: " + newTime); Editor configEditor = config.edit(); configEditor.putInt(String.format("UpdateRate-%d", widgetId), newTime); configEditor.commit(); // Envia o RESULT_OK... Intent i = new Intent(); i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); setResult(RESULT_OK, i); // tell the app widget manager that we're now // configured // Pega o context Context context = getApplicationContext(); // updateAllWidgets(); Intent intent = new Intent(); intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); //intent.setData(Uri.parse("widget_quotes_://widget/id/" // + widgetId)); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { widgetId }); PendingIntent newPending = PendingIntent.getBroadcast(context, widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT); // schedule the new widget for updating AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarms.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), newTime * 1000, newPending); System.out.println("Configuração finalizada..."); } } finish(); } } Everything else is working fine (it is updating as it should and everything, just doesn't show a thing), but, if you want I can update here and post more code. Thanks. -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

