我试图比1.6docs施加的30分钟限制更频繁地更新Widget。在阅读了SO中的几乎所有帖子,以及开发人员文档和其他各种来源之后,我认为我已经达到了可以实现它的程度。所以,我尝试过,但失败了。从那时起,我已经搜索了更多的论坛和解决方案,我似乎无法更新它。
我有一个Update类来设置AlarmManager:
public class Update extends Service{
@Override
public void onStart(Intent intent, int startId) {
String currentTemp = Battery.outputTemp;
String currentLevel = Battery.outputLevel;
String currentCard = Battery.outputCard;
String currentInternal = Battery.memory;
String currentRam = String.valueOf(Battery.outputRam).substring(0, 3) + "MB";
// Change the text in the widget
RemoteViews updateViews = new RemoteViews(
this.getPackageName(), R.layout.main);
//update temp
updateViews.setTextViewText(R.id.batteryTemp, currentTemp);
//update %
updateViews.setTextViewText(R.id.batteryLevel, currentLevel);
//update level
updateViews.setTextViewText(R.id.sdCard, currentCard);
//update internal memory
updateViews.setTextViewText(R.id.internal, currentInternal);
//update ram
updateViews.setTextViewText(R.id.ram, currentRam);
ComponentName thisWidget = new ComponentName(this, Widget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
@Override
public IBinder onBind(Intent intent) {
// no need to bind
return null;
}
}
这导致我的widget类中的onReceive经常触发(我有一个toast来查看它何时触发),但它没有意图(toast意味着显示这个,因为它们被收到但是它是空白的)。
我无法弄明白(我是一个相对较新的2个月的慢速Android开发者),并欣赏你们有任何见解。
继承我的widget类供参考:
public class Widget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
AlarmManager alarmManager;
Intent intent = new Intent(context, Update.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal
.getTimeInMillis(), 5 * 1000, pendingIntent);
String currentTemp = Battery.outputTemp;
String currentLevel = Battery.outputLevel;
String currentCard = Battery.outputCard;
String currentInternal = Battery.memory;
String currentRam = String.valueOf(Battery.outputRam).substring(0, 3)
+ "MB";
// Change the text in the widget
RemoteViews updateViews = new RemoteViews(context.getPackageName(),
R.layout.main);
// update temp
updateViews.setTextViewText(R.id.batteryTemp, currentTemp);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
// update %
updateViews.setTextViewText(R.id.batteryLevel, currentLevel);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
// update level
updateViews.setTextViewText(R.id.sdCard, currentCard);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
// update internal memory
updateViews.setTextViewText(R.id.internal, currentInternal);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
// update ram
updateViews.setTextViewText(R.id.ram, currentRam);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Toast
.makeText(context, intent.getAction() + context,
Toast.LENGTH_LONG).show();
Bundle extras = intent.getExtras();
if (extras != null) {
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
ComponentName thisAppWidget = new ComponentName(context
.getPackageName(), Widget.class.getName());
int[] appWidgetIds = appWidgetManager
.getAppWidgetIds(thisAppWidget);
onUpdate(context, appWidgetManager, appWidgetIds);
}
}
}
我有一个Update类来设置AlarmManager:
不,你没有。 AlarmManager
在代码片段中没有出现。
你确实在第二个代码片段中引用了AlarmManager
。问题包括:
_WAKEUP
警报上设置了5秒的频率,我认为这是你在某些司法管辖区被捕的理由onReceive()
方法,甚至忽略了临时的Toast
Intent
中的Toast
上会有一个动作字符串,但是当你创建你在Intent
中为警报放置的PendingIntent
时你没有指定一个动作字符串Battery
类上的静态数据成员,但很可能那些都是空的/ null ...或者至少它们会是,如果你有一个合理的报警频率这是我的解决方案,如何比30分钟更频繁地自动更新小部件。我使用AlarmManager。在使用AlarmManager刷新appwidget之前,请确保您知道自己在做什么,因为这种技术可能会耗尽设备的电量。
在Android文档中阅读有关widget update的更多信息 - 特别是关于updatePeriodMillis参数。
这是我的Manifest.xml的一部分。我定义自定义操作AUTO_UPDATE。
<receiver android:name=".appwidget.AppWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<intent-filter>
<action android:name="AUTO_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_info" />
</receiver>
这是我的AppWidget.java的一部分。在onReceive方法中,我处理自定义操作AUTO_UPDATE。在onEnabled和onDisabled方法中,我启动/停止警报。
public class AppWidget extends AppWidgetProvider
{
public static final String ACTION_AUTO_UPDATE = "AUTO_UPDATE";
@Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
if(intent.getAction().equals(ACTION_AUTO_UPDATE))
{
// DO SOMETHING
}
...
}
@Override
public void onEnabled(Context context)
{
// start alarm
AppWidgetAlarm appWidgetAlarm = new AppWidgetAlarm(context.getApplicationContext());
appWidgetAlarm.startAlarm();
}
@Override
public void onDisabled(Context context)
{
// stop alarm only if all widgets have been disabled
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisAppWidgetComponentName = new ComponentName(context.getPackageName(),getClass().getName());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidgetComponentName);
if (appWidgetIds.length == 0) {
// stop alarm
AppWidgetAlarm appWidgetAlarm = new AppWidgetAlarm(context.getApplicationContext());
appWidgetAlarm.stopAlarm();
}
}
...
}
这是我的AppWidgetAlarm.java,它启动/停止警报。警报管理器向AppWidget发送广播。
public class AppWidgetAlarm
{
private final int ALARM_ID = 0;
private final int INTERVAL_MILLIS = 10000;
private Context mContext;
public AppWidgetAlarm(Context context)
{
mContext = context;
}
public void startAlarm()
{
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MILLISECOND, INTERVAL_MILLIS);
Intent alarmIntent = new Intent(AppWidget.ACTION_AUTO_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, ALARM_ID, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
// RTC does not wake the device up
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), INTERVAL_MILLIS, pendingIntent);
}
public void stopAlarm()
{
Intent alarmIntent = new Intent(AppWidget.ACTION_AUTO_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, ALARM_ID, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
}
感谢这个例子 - 我在使用更高版本的Android时也遇到了问题。
这篇文章让它对我有用:widget case that doesn't work(参见Larry Schiefer的回答)。
所以从上面的代码中替换它:
Intent alarmIntent = new Intent(AppWidget.ACTION_AUTO_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, ALARM_ID, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
来自ref的这个:
Intent alarmIntent=new Intent(mContext, MyWidget.class);
alarmIntent.setAction(AppWidget.ACTION_AUTO_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, ALARM_ID, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
做了这个工作。