いくつかのウィジェットを持つ Android アプリケーションを作成しています。設定アクティビティの作成を開始するまで、すべてが機能していました...まず、私のコード:
[編集] 明確にするために: バンドル (intent.getExtras() から) は常に null です...修正するにはどうすればよいですか? [/編集]
AppWidgetProvider:
package com.br.mcsoft.atheistquotes.provider;
import com.br.mcsoft.atheistquotes.R;
import com.br.mcsoft.atheistquotes.Adapters.DBAdapter;
import com.br.mcsoft.atheistquotes.activity.QuoteActivity;
import com.br.mcsoft.atheistquotes.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.database.SQLException;
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";
private static Quote lastQuote = null;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
System.out.println("Updatando...");
super.onUpdate(context, appWidgetManager, appWidgetIds);
final int n = appWidgetIds.length;
for (int i = 0; i < n; i++) {
updateData(context, i);
System.out.println("Atualizou os dados...");
// Cria o RemoteViews
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.widget_layout_small);
// Adiciona o listener do evento do botão Next...
Intent active = new Intent(context, WidgetProviderSmall.class);
active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetIds[i]);
active.setAction(StaticHelper.ACTION_WIDGET_REFRESH);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(
context, 0, 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);
actionPendingIntent = PendingIntent.getBroadcast(context, 0,
active, 0);
rv.setOnClickPendingIntent(R.id.laySmall, actionPendingIntent);
// Atualiza tudo
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
}
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
System.out.println("Recebeu alguma chamada...");
if (intent.getAction().equals(StaticHelper.ACTION_WIDGET_REFRESH)) {
// Log.i("onReceive", ACTION_WIDGET_REFRESH);
Bundle extras = intent.getExtras();
if (extras != null) {
int widgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
updateData(context, widgetId);
}
} else if (intent.getAction().equals(StaticHelper.ACTION_CLICK)) {
Intent i = new Intent(context, QuoteActivity.class);
Bundle b = new Bundle();
b.putInt("QuoteId", lastQuote.getId());
i.putExtras(b);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
System.out.println("Ih! OnDelete!");
Intent intent = new Intent(context, WidgetProviderSmall.class);
Bundle extras = intent.getExtras();
if (extras != null) {
int widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
AlarmManager alarms = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent widgetUpdate = new Intent();
widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
new int[] { widgetId });
PendingIntent newPending = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Para o alarme...
alarms.cancel(newPending);
// Remove o estado armazenado...
SharedPreferences config = context.getSharedPreferences(
"AtheistQuoteWidget", 0);
SharedPreferences.Editor edit = config.edit();
edit.remove(String.format("UpdateRate-%d", widgetId));
edit.commit();
}
super.onDeleted(context, appWidgetIds);
}
private void updateData(Context context, int Id) {
try {
DBAdapter db;
db = new DBAdapter(context);
db.open();
Quote q = db.getRandomQuote();
db.close();
lastQuote = q;
// Verifica o tamanho e trunca o texto da citação...
String textQuote = "\"" + q.getQuote() + "\"";
if (textQuote.length() > 110 + 10) {
textQuote = textQuote.substring(0, 110) + "...\" [...]";
}
// Cria o RemoteViews
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.widget_layout_small);
// Seta os campos...
// rv.setTextViewText(R.id.txtWdgQuote, "\"" + q.getQuote() + "\"");
rv.setTextViewText(R.id.txtWdgQuote, textQuote);
rv.setTextViewText(R.id.txtWdgAuthor, "— "
+ q.getAuthor().getName());
// Atualiza tudo
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
appWidgetManager.updateAppWidget(Id, rv);
} catch (SQLException e) {
Log.e(TAG, e.getMessage(), e);
}
}
}
アクティビティ:
package com.br.mcsoft.atheistquotes.activity;
import com.br.mcsoft.atheistquotes.R;
import com.br.mcsoft.atheistquotes.provider.WidgetProviderSmall;
import android.net.Uri;
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.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
public class SettingsActivity extends Activity {
private static final String[] Times = new String[] { "5 minut",
"10 minuts", "15 minuts", "20 minuts", "30 minuts", "1 hora",
"2 horas" };
private static int DEFAULT_TIME = 15;
private int oldTime = 0;
private int newTime;
private Spinner spn = null;
private SharedPreferences config = null;
private int widgetId;
@Override
public void onCreate(Bundle savedInstanceState) {
// Inicia a excução...
System.out.println("Entrou...");
super.onCreate(savedInstanceState);
System.out.println("Chamou o super e o layoyt...");
widgetId = 0;
// Pega o Id do Widget
Intent intent = new Intent(this, WidgetProviderSmall.class);
Bundle extras = intent.getExtras();
if (extras != null) {
System.out.println("Há extras...");
widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
} else {
System.out.println("Ferrou, não há...");
finish();
return;
}
// Seta como "cancelar" preventivamente...
Intent cancelResultValue = new Intent(this, WidgetProviderSmall.class);
cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
widgetId);
setResult(RESULT_CANCELED, cancelResultValue);
System.out.println("Setou o cancel...");
// Verifica o tempo atualmente setado
config = this.getSharedPreferences("AtheistQuoteWidget", 0);
try {
oldTime = config.getInt(String.format("UpdateRate-%d", widgetId),
-1);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Pegou o tempo setado...");
// Seta o Spinner...
setContentView(R.layout.activity_settings);
System.out.println("Chamou o layout...");
spn = (Spinner) findViewById(R.id.spnTimes);
ArrayAdapter<String> adp = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, Times);
adp.setDropDownViewResource(android.R.layout.simple_spinner_item);
spn.setAdapter(adp);
if (oldTime == 0)
oldTime = DEFAULT_TIME;
// Seta o tempo atual no Spinner
if (oldTime == 5) {
spn.setSelection(0);
} else if (oldTime == 5) {
spn.setSelection(1);
} else if (oldTime == 10) {
spn.setSelection(2);
} else if (oldTime == 15) {
spn.setSelection(3);
} else if (oldTime == 20) {
spn.setSelection(4);
} else if (oldTime == 30) {
spn.setSelection(5);
} else if (oldTime == 60) {
spn.setSelection(6);
} else if (oldTime == 120) {
spn.setSelection(7);
}
System.out.println("Setou o Spinner...");
// Pega e seta os botões...
Button ok = (Button) findViewById(R.id.btnOk);
Button cancel = (Button) findViewById(R.id.btnCancel);
ok.setOnClickListener(buttonClick);
cancel.setOnClickListener(buttonClick);
System.out.println("Setou os botões...");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_settings, menu);
return true;
}
private OnClickListener buttonClick = new OnClickListener() {
public void onClick(View v) {
if (v == (Button) findViewById(R.id.btnOk)) {
newTime = spn.getSelectedItemPosition();
if (newTime == oldTime) {
finish();
}
SharedPreferences.Editor configEditor = config.edit();
configEditor.putInt(String.format("UpdateRate-%d", widgetId),
newTime);
configEditor.commit();
if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
// tell the app widget manager that we're now configured
Intent i = new Intent();
i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
setResult(RESULT_OK, i);
Intent widgetUpdate = new Intent();
widgetUpdate
.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
new int[] { widgetId });
// make this pending intent unique
widgetUpdate.setData(Uri.withAppendedPath(Uri
.parse(WidgetProviderSmall.URI_SCHEME + "://widget/id/"),
String.valueOf(widgetId)));
PendingIntent newPending = PendingIntent.getBroadcast(
getApplicationContext(), 0, widgetUpdate,
PendingIntent.FLAG_UPDATE_CURRENT);
// schedule the new widget for updating
AlarmManager alarms = (AlarmManager) getApplicationContext()
.getSystemService(Context.ALARM_SERVICE);
alarms.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime(), newTime * 1000,
newPending);
}
// activity is now done
finish();
}
}
};
}
「System.out.println」はデバッグ用です (テキストはポルトガル語です。ポルトガル語が私の母国語なので)。
とにかく、問題はここに示されています:
if (extras != null) {
System.out.println("Há extras...");
widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
} else {
System.out.println("Ferrou, não há...");
finish();
return;
}
それは常に他のものに行きます...したがって、すべてがエラーなしで失敗しました。:/
それが機能するために私がしなければならないことは何ですか?AndroidManifest.xml などを変更する必要がありますか?
ありがとう!
PS: うーん... Android 開発はまったくの初心者です... 何か変なところがあれば教えてください。