Intereting Posts

Android Виджет onReceive не может вызвать класс обслуживания?

У меня есть widgetProvider. У меня также есть класс обслуживания, который вычисляет для виджета.

Виджет отлично работает при инициализации. Я получаю сообщение об ошибке, когда пытаюсь вызвать службу из метода onReceive после трансляции, на которую я хочу реагировать (изменение времени).

Как обновить виджет из onReceive после получения широковещательного события?

Вот мой виджет

public class HijriWidget extends AppWidgetProvider{ ... @Override public void onReceive(Context context, Intent intent) { if(Intent.ACTION_TIME_CHANGED.equals(intent.getAction())||Intent.ACTION_DATE_CHANGED.equals(intent.getAction())){ //THE CODE BELOW LEADS TO AN EXCEPTION. HOW CAN I UPDATE THE WIDGET HERE? RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID); appWidgetManager.updateAppWidget(appWidgetId, remoteView); } super.onReceive(context, intent); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) { for (int appWidgetId : appWidgetIds) { PendingIntent updatepending = HijriWidget.makeControlPendingIntent(context,RefreshService.UPDATE, appWidgetId); pi = updatepending; try { updatepending.send(); } catch (CanceledException e) { e.printStackTrace(); } setAlarm(context, appWidgetId, 5*60*1000); } super.onUpdate(context, appWidgetManager, appWidgetIds); } public static PendingIntent makeControlPendingIntent(Context context, String command, int appWidgetId) { Intent active = new Intent(context,RefreshService.class); active.setAction(command); active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); //this Uri data is to make the PendingIntent unique, so it wont be updated by FLAG_UPDATE_CURRENT //so if there are multiple widget instances they wont override each other Uri data = Uri.withAppendedPath(Uri.parse("hijriwidget://widget/id/#"+command+appWidgetId), String.valueOf(appWidgetId)); active.setData(data); return(PendingIntent.getService(context, 0, active, PendingIntent.FLAG_UPDATE_CURRENT)); } public static void setAlarm(Context context, int appWidgetId, int updateRate) { PendingIntent newPending = makeControlPendingIntent(context,RefreshService.UPDATE,appWidgetId); AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); if (updateRate >= 0) { alarms.set( AlarmManager.RTC, calendar.getTimeInMillis(), newPending); //alarms.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), updateRate, newPending); } else { // on a negative updateRate stop the refreshing alarms.cancel(newPending); } } 

}

И вот моя услуга

 public class RefreshService extends Service { @Override public void onStart(Intent intent, int startId) { int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID); RemoteViews remoteView = new RemoteViews(getApplicationContext() .getPackageName(), R.layout.widget); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext()); final Calendar c = Calendar.getInstance(); int mYear = c.get(Calendar.YEAR); int mMonth = c.get(Calendar.MONTH); int mDay = c.get(Calendar.DAY_OF_MONTH); int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); mMonth++; HijriCalendar hc =new HijriCalendar( mYear,mMonth,mDay); remoteView.setTextViewText(R.id.TextView02,hc.getHijriMonth()+"/"+hc.getHijriDay()); remoteView.setTextColor(R.id.TextView02, Color.BLACK); remoteView.setTextViewText(R.id.TextView01, hc.getHijriYear()+""); remoteView.setTextColor(R.id.TextView01, Color.WHITE); appWidgetManager.updateAppWidget(appWidgetId, remoteView); super.onStart(intent, startId); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } 

Любая помощь будет оценена по достоинству. Благодарю.

ОБНОВИТЬ:

Я нашел проблему. Проверьте мой ответ ниже.

Solutions Collecting From Web of "Android Виджет onReceive не может вызвать класс обслуживания?"

Думаю, вы поняли это, но проблема в вашем исходном коде заключалась в том, что в намерении ACTION_TIME_CHANGED не добавляется приложение AppWidgetManager.EXTRA_APPWIDGET_ID, поэтому getInt () выбрасывает исключение nullpointer.

Примечание. Существует несколько более простой способ решить эту проблему: один из переопределений updateAppWidget принимает имя компонента вместо идентификатора виджета, поэтому вы можете создать общую функцию для обновления виджета и вызвать его как из onReceive, так и onUpdate, например:

 private static void updateWidget(Context context) { AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); // ... code here to build your remoteviews ... ComponentName widgetComponent = new ComponentName(PACKAGE, PACKAGE+"."+CLASS); appWidgetManager.updateAppWidget(widgetComponent, remoteView); } 

Тогда вам никогда не придется беспокоиться об идентификаторах виджетов. Конечно, это работает, только если вы не заботитесь о поддержке нескольких одновременных виджетов.

См. http://developer.android.com/reference/android/appwidget/AppWidgetManager.html#updateAppWidget%28android.content.ComponentName,%20android.widget.RemoteViews%29

ОБНОВИТЬ:

Я поставил ниже код в методе onReceive, и это сработало для меня

 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); ComponentName thisAppWidget = new ComponentName(PACKAGE, PACKAGE+"."+CLASS); int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget); try { onUpdate(context, appWidgetManager, appWidgetIds); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }