2010-07-27 19 views
7

Bir widgetProvider'ım var. Ayrıca widget için hesaplama yapan bir hizmet sınıfım var.Android Widget onReceive Hizmet sınıfı'nı arayamaz?

Widget, başlatıldığında iyi çalışır. Tepki vermek istediğim bir yayın olayından sonra (time change) onReceive yönteminden hizmeti çağırmaya çalıştığımda bir hata alıyorum.

Bir yayın etkinliğini aldıktan sonra widget'ı onReceive'dan nasıl güncelleyebilirim?

İşte benim Widget

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); 
      } 
     } 

} burada

ve herhangi bir yardım takdir edilecektir

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; 
} 

benim hizmet olmasıdır. Teşekkürler.

GÜNCELLEME: Ben sorunu buldum

. Cevabımı aşağıda kontrol edin.

+1

çalıştı

Ne istisna olsun? – Pentium10

+0

java.lang.RuntimeException: alıcısını başlatılamıyor ... Neden Olduğu com.majjoodi.hijri.HijriWidget: com.majjoodi.hijri.HijriWidget.onRecieve – Majjoodi

+0

de java.lang.NullPointerException hiçbir güncellemeyi var mı? – robertokl

cevap

0

GÜNCELLEME: Ben OnReceive yönteminde aşağıdaki kodu koyduk ve bana

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(); 

       } 
2

sanırım bu anladım, ancak orijinal kodda sorun ACTION_TIME_CHANGED niyet GETINT böylece() bir NullPointerException atma ekstra bir AppWidgetManager.EXTRA_APPWIDGET_ID içermez olmasıydı.

Not: Bu sorunu çözmek için biraz daha kolay bir yol var: updateAppWidget öğesinin geçersiz kılmalarından biri, pencere öğesi kimliği yerine bir componentname alır; böylece, widget'ı güncelleştirmek ve hem onReceive hem de ondan almak için ortak bir işlev oluşturabilirsiniz. onUpdate, örn .:

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); 
} 

Ardından, widget'lar hakkında endişelenmenize gerek kalmaz. Tabii ki bu sadece birden fazla eşzamanlı widget'ı desteklemezseniz işe yarar.

bakınız: http://developer.android.com/reference/android/appwidget/AppWidgetManager.html#updateAppWidget%28android.content.ComponentName,%20android.widget.RemoteViews%29

İlgili konular